【问题标题】:Verifying a method call in a base class that takes a delegate parameter using Moq使用 Moq 验证采用委托参数的基类中的方法调用
【发布时间】:2014-01-03 21:45:42
【问题描述】:

我正在尝试测试是否调用了一个方法,并且该方法存在于被测类的基类中。

当我使用简单的字符串参数运行以下示例时,它可以工作,但是当有委托参数时,测试失败。

我创建了以下示例来演示该问题。如果在SomeMethod中取出delegate参数,在测试中,测试就通过了。

失败代码:

public abstract class BaseClass
{
    public virtual void SomeMethod(string someString, Func<bool> function)
    {
        //do something
    }
}

public class DerivedClass : BaseClass
{
    public void DoSomething()
    {
        SomeMethod("foo", () => true);
    }
}

[TestClass]
public class Tests
{
    [TestMethod]
    public void TestMethod1()
    {
        var test = new Mock<DerivedClass>();
        test.Object.DoSomething();
        test.Verify(x => x.SomeMethod("foo", () => true), Times.AtLeastOnce);
    }
}

通过代码:

public abstract class BaseClass
{
    public virtual void SomeMethod(string someString)
    {
        //do something
    }
}

public class DerivedClass : BaseClass
{
    public void DoSomething()
    {
        SomeMethod("foo");
    }
}

[TestClass]
public class Tests
{
    [TestMethod]
    public void TestMethod1()
    {
        var test = new Mock<DerivedClass>();
        test.Object.DoSomething();
        test.Verify(x => x.SomeMethod("foo"), Times.AtLeastOnce);
    }
}

测试失败的错误信息:

Expected invocation on the mock at least once, but was never performed: x => x.SomeMethod("foo", () => True)
No setups configured.

Performed invocations:
BaseClass.SomeMethod("foo", System.Func1[System.Boolean])`

整个错误信息:

Test method UnitTestProject1.Tests.TestMethod1 threw exception: 
Moq.MockException: 
Expected invocation on the mock at least once, but was never performed: x => x.SomeMethod("foo", () => True)
No setups configured.

Performed invocations:
BaseClass.SomeMethod("foo", System.Func`1[System.Boolean])
   at Moq.Mock.ThrowVerifyException(MethodCall expected, IEnumerable`1 setups, IEnumerable`1 actualCalls, Expression expression, Times times, Int32 callCount)
   at Moq.Mock.VerifyCalls(Interceptor targetInterceptor, MethodCall expected, Expression expression, Times times)
   at Moq.Mock.Verify(Mock`1 mock, Expression`1 expression, Times times, String failMessage)
   at Moq.Mock`1.Verify(Expression`1 expression, Times times)
   at Moq.Mock`1.Verify(Expression`1 expression, Func`1 times)
   at UnitTestProject1.Tests.TestMethod1() in UnitTest1.cs: line 16

【问题讨论】:

    标签: c# unit-testing delegates mocking moq


    【解决方案1】:

    如果我将测试更改为跟随它通过。请参阅我将 () =&gt; true 更改为 It.IsAny&lt;Func&lt;bool&gt;&gt;(),这意味着它可以使用任何 Func 调用。你在乎它是不是() =&gt; true

    var test = new Mock<DerivedClass>();
    test.Object.DoSomething();
    test.Verify(x => x.SomeMethod("foo", It.IsAny<Func<bool>>()), Times.AtLeastOnce);
    

    【讨论】:

    • 谢谢。该示例只是演示问题的一个简单示例。您的回答启发了解决实际问题的方法。我还没有足够的代表来支持你的答案。
    • @will 这个答案正确的原因是两个代表Func&lt;bool&gt; d1 = () =&gt; true;Func&lt;bool&gt; d2 = () =&gt; true; 不需要比较相等,即d1.Equals(d2) 可以返回false。有关目标方法(以及非静态方法的目标实例)必须相同的说明,请参见 Equals method documentation。然而,()=&gt;true 可能会创建一个 new “真实”方法,即使另一个 ()=&gt;true 已经存在于其他地方。在这里,两个 lambdas 甚至属于不同的类。一个在表达式树中。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-26
    • 2011-03-08
    • 2011-07-11
    • 1970-01-01
    相关资源
    最近更新 更多