【问题标题】:Testing a method accepting a delegate with Moq使用 Moq 测试接受委托的方法
【发布时间】:2015-09-16 06:32:17
【问题描述】:

我的代码正在使用一个组件来实现这样的接口

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(... 行不平衡(它们缺少 Setup() 的右括号。这只是复制粘贴错误吗?当我修复它时,您的第二行(It.IsAny >()) 对我来说很好。
  • 这是一个复制粘贴错误。而且,确实,现在它正在构建。尽管如此,能够对 Action 的内容进行某种断言还是很有趣的。
  • 但这会给你什么?当您在测试其他方法 Bar 时,您将模拟 IFoo,并且您知道 Bar 将调用 This.myFoo.DoSomething("bar", myAction); 对于 Bar 上的测试,Foo 对象对传递给它的操作做了什么并不重要; IFoo 不返回任何数据。您是否依赖于代码中调用 DoSomething 的 Action p2 的副作用?

标签: c# unit-testing delegates moq


【解决方案1】:

行:

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

必须编译,因为DoSomething 需要Action&lt;string&gt;,并且Delegate 不能隐式转换为Action&lt;string&gt;。你的另一行:

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&lt;string&gt;的数量是有限制的,但是你可以看看它是否非空,看看它的p2.Target是非空还是具有特定类型或等于给定实例,您可以查看 p2.Method 是否是已知(命名)方法,或者如果您期望所谓的多播委托,则可以使用 p2.GetInvocationList()

【讨论】:

  • 谢谢!您的回答给了我一个帮助我解决问题的想法。我所做的只是提取一个服务来处理 Action 的逻辑。在测试中,我只是验证了第二个服务被正确调用。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-21
  • 2013-08-24
  • 2016-08-21
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多