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

时间:2009-09-17 04:49:49

标签: 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";
    }
}

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

感谢您的任何建议。

3 个答案:

答案 0 :(得分:17)

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

答案 1 :(得分:11)

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

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

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

答案 2 :(得分:2)

你正在做这个人在这里做的事情: How to Verify another method in the class was called using Moq

你正在嘲笑你在测试什么。这没有意义。使用Mocks是为了隔离。您的Can_Do_Something测试将始终通过。无论。这不是一个好的测试。

仔细看看Gishu的测试或我在链接SO问题中提出的测试。