单元测试:验证一个方法是否被调用,在测试方法中创建一个对象作为参数

Unit testing: verifying a method was called, with an object created inside the tested method as parameter

问题描述

要测试的方法创建某种类型的对象,我们称之为Item。它使用传入的数据初始化这些对象的属性。

此方法调用另一个方法,该方法将 Item 作为参数。如何确保调用正确?也就是说,需要验证以下内容:

  1. 传递给方法的对象类型正确。
  2. 传递给方法的对象具有正确的 属性 值。
  3. 另一个方法被调用的次数正确。

假设我们正在使用 NUnit 和 FakeItEasy。

代码

public class Controller
{
    IService service {get; set;}

    // dependency injection, can use fakes
    public Controller(IService service) {
        this.service = service;
    }

    public void methodToTest(string itemName, string itemDescription, int quantity)
    {
        Item newItem = new Item
        {
            name = name,
            description = description
        }

        for (int i = 1; i <= quantity; i++)
        {
            // need to verify that doSomething() is called with a parameter of type Item
            // and that it is called quantity times
            // and that newItem has correct parameters
            service.doSomething(newItem);
        }
    }
}

你可以试试这个:

    [Test]
    public void MethodToTest_Should_Call_Service_Correctly()
    {
        var service = A.Fake<IService>();

        var controller = new Controller(service);
        controller.methodToTest("some-item", "some-description", 5);

        var expectedItem = new Item
        {
            Name = "some-item",
            Description = "some-description"
        };
        A.CallTo(() => service.DoSomething(expectedItem)).MustHaveHappened(5, Times.Exactly);
    }

请注意,过多的模拟会导致严格的测试,因为它们与实现细节有关。