Foq supports a Returns : unit -> 'TValue method so you can lazily create a value.
Using a little mutation instances can refer to each other:
type IPublishChannel =
abstract Bus : IBus
and IBus =
abstract OpenPublishChannel : unit -> IPublishChannel
let mutable mockBus : IBus option = None
let mutable mockChannel : IPublishChannel option = None
mockChannel <-
Mock<IPublishChannel>()
.Setup(fun x -> <@ x.Bus @>).Returns(fun () -> mockBus.Value)
.Create()
|> Some
mockBus <-
Mock<IBus>()
.Setup(fun x -> <@ x.OpenPublishChannel() @>).Returns(fun () -> mockChannel.Value)
.Create()
|> Some