質問

I'd let to mock an IBus with Foq.

One of the methods on the IBus is OpenPublishChannel, which returns an IPublishChannel. IPublishChannel in turn has a Bus property that returns the parent IBus.

My current code is below, but obviously it doesn't compile as mockBus is not defined by the point I need it. Is there a way of setting up recursive mocking like this without creating two mocks of either interface?

open System
open EasyNetQ
open Foq

let mockChannel = 
    Mock<IPublishChannel>()
        .Setup(fun x -> <@ x.Bus @>).Returns(mockBus)
        .Create()
let mockBus =
    Mock<IBus>()
        .Setup(fun x -> <@ x.OpenPublishChannel() @>).Returns(mockChannel)
        .Create()
役に立ちましたか?

解決

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
ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top