使用 Moq 测试接受委托的方法

Testing a method accepting a delegate with Moq

我的代码使用的组件实现了这样的接口

public interface IFoo 
{ 
    void DoSomething(string p1);

    void DoSomething(string p1, Action<string> p2);
}

截至目前,我使用的是第一种方法,但我打算转向第二种方法,并且我希望保持尽可能高的覆盖率。

只是我真的不知道如何检查委托,甚至不知道如何设置 Moq 来模拟接口。

我试过

mock.Setup(p => p.DoSomething(It.IsAny<string>(), It.IsAny<Delegate>()));
mock.Setup(p => p.DoSomething(It.IsAny<string>(), It.IsAny<Action<string>>()));

但都不会让我建造。有什么建议吗?

行:

mock.Setup(p => p.DoSomething(It.IsAny<string>(), It.IsAny<Delegate>()));

必须不能编译,因为DoSomething需要一个Action<string>,而Delegate不是隐式 可转换为 Action<string>。您的另一条线路:

mock.Setup(p => p.DoSomething(It.IsAny<string>(), It.IsAny<Action<string>>()));

有效且正确!

只有p2满足一些条件才可以设置,例如:

mock.Setup(p => p.DoSomething(It.IsAny<string>(),
    It.Is((Action<string> p2) => p2 != null && p2.Target is SomeClass)
    ));

或者您可以使用 CallBack 检查内容:

mock.Setup(p => p.DoSomething(It.IsAny<string>(), It.IsAny<Action<string>>()))
    .CallBack((string p1, Action<string> p2) =>
    {
        // your code (for example Asserts) here,
        // use p2
    });

当然,你可以检查一个 Action<string> 的程度是有限制的,但你可以查看它是否非空,看看它是否 p2.Target 为非空或具有特定类型或等于给定实例,您可以查看 p2.Method 是否为已知(命名)方法,或者如果您期望这样,则可以使用 p2.GetInvocationList() -称为多播委托。