未能替代

Failing to substitude

[Theory]
[InlineData("12345678901","bob")]
[InlineData("12345678902", "alice")]
public void Customer_Registration_Should_Succeed(string identityId, string name)
{
    Customer customer = new Customer(identityId, name);

    _customerRepository.Add(customer).Returns(customer);

    var customerService = new CustomerService(_customerRepository);

    var expectedCustomer = customerService.Register(identityId, name);

    Assert.Equal(expectedCustomer, customer);

}

我有上面的测试代码

这是服务:

public class CustomerService : ICustomerService
{
    readonly ICustomerRepository _customerRepository;
    public CustomerService(ICustomerRepository customerRepository)
    {
        _customerRepository = customerRepository;
    }

    public Customer Register(IdentityId identityId, Name name)
    {
        var customer = new Customer(identityId, name);
        var newCustomer = _customerRepository.Add(customer);

        return newCustomer;
    }
}

下面是存储库:

public class CustomerRepository : ICustomerRepository
{
    IList<Customer> _customers;

    public CustomerRepository()
    {
        _customers = new List<Customer>();
    }

    public Customer Add(Customer customer)
    {
        _customers.Add(customer);

        return customer;
    }
}

但是我得到空引用异常。

Assert.Equal(expectedCustomer, customer);

断言失败。为什么?

正在创建两个单独的实例,

正在测试的方法。

public Customer Register(IdentityId identityId, Name name)
{
    var customer = new Customer(identityId, name); //<-- HERE
    var newCustomer = _customerRepository.Add(customer);

    return newCustomer;
}

和测试

//...

Customer customer = new Customer(identityId, name); // <--HERE

_customerRepository.Add(customer).Returns(customer);

//...

问题是测试中的实例被用作配置替代的参数。

替换将期望来自设置的确切实例,但被测方法正在传递它自己的实例,这将导致替换为 return null,因为参数不匹配。

一个选项是将替代设置为 return 传递给被调用成员的参数。

例如

_customerRepository.Add(Arg.Any<Customer>()).Returns(_ => _.Arg<Customer>());

可以根据需要断言

[Theory]
[InlineData("12345678901","bob")]
[InlineData("12345678902", "alice")]
public void Customer_Registration_Should_Succeed(string identityId, string name) {
    //Arrange
    _customerRepository.Add(Arg.Any<Customer>()).Returns(_ => _.Arg<Customer>());
    var customerService = new CustomerService(_customerRepository);

    //Act
    var actual = customerService.Register(identityId, name);

    //Assert
    Assert.IsNotNull(actual);
    Assert.AreEqual(actual.IdentityId, identityId);
    Assert.AreEqual(actual.Name, name);

    //Check received with the arg:
    _customerRepository.Received().Add(actual);
}