Moq:指定返回值作为期望的一部分

17 moq

我是Moq的新手并且正在学习.

我需要测试一个方法返回预期的值.我已经整理了一个例子来解释我的问题.这失败了:

"ArgumentException:Expression不是方法调用:c =>(c.DoSomething("Jo","Blog",1)="OK")"

你能纠正我做错的事吗?

[TestFixtureAttribute, CategoryAttribute("Customer")]
public class Can_test_a_customer
{
    [TestAttribute]
    public void Can_do_something()
    {
        var customerMock = new Mock<ICustomer>();

        customerMock.Setup(c => c.DoSomething("Jo", "Blog", 1)).Returns("OK");

        customerMock.Verify(c => c.DoSomething("Jo", "Blog", 1)=="OK");
    }
}

public interface ICustomer
{
    string DoSomething(string name, string surname, int age);
}

public class Customer : ICustomer
{
    public string DoSomething(string name, string surname, int age)
    {
        return "OK";
    }
}
Run Code Online (Sandbox Code Playgroud)

简而言之:如果我想测试一个像上面那样的方法,并且我知道我期待回到"OK",我将如何使用Moq编写它?

谢谢你的任何建议.

Gis*_*shu 18

  1. 你需要一个与模拟对象交互的测试主题(除非你正在为Moq编写一个学习者测试.)我在下面写了一个简单的测试
  2. 您在模拟对象上设置期望,指定确切的参数(严格 - 如果您希望当然,否则使用Is.Any<string>接受任何字符串)并指定返回值(如果有)
  3. 您的测试对象(作为测试法案步骤的一部分)将调用您的模拟
  4. 您断言测试主体的行为符合要求.测试主题将使用模拟方法的返回值 - 通过测试主题的公共接口进行验证.
  5. 您还验证是否满足了您指定的所有期望 - 实际上调用了您希望调用的所有方法.

.

[TestFixture]
public class Can_test_a_customer
{
  [Test]
  public void Can_do_something()
  {
    //arrange
    var customerMock = new Moq.Mock<ICustomer>();
    customerMock.Setup(c => c.DoSomething( Moq.It.Is<string>(name => name == "Jo"),
         Moq.It.Is<string>(surname => surname == "Blog"),
         Moq.It.Is<int>(age => age == 1)))
       .Returns("OK");

    //act
    var result = TestSubject.QueryCustomer(customerMock.Object);

    //assert
    Assert.AreEqual("OK", result, "Should have got an 'OK' from the customer");
    customerMock.VerifyAll();
  }
}

class TestSubject
{
  public static string QueryCustomer(ICustomer customer)
  {
    return customer.DoSomething("Jo", "Blog", 1);
  }
}
Run Code Online (Sandbox Code Playgroud)


Mat*_*ton 12

Mock<T>.Verify 不返回方法调用返回的值,因此您不能使用"=="将其与预期值进行比较.

实际上,Verify没有重载返回任何内容,因为您永远不需要验证mocked方法返回特定值.毕竟,有责任将其设置为首先返回该值!模拟方法的返回值将由您正在测试的代码使用 - 您不是在测试模拟.

使用"验证"确认使用您期望的参数调用方法,或者为属性分配了预期的值.当您进入测试的"断言"阶段时,模拟方法和属性的返回值并不重要.