0

我刚刚开始进行单元测试,现在坚持编写删除测试方法。我正在使用 MStest 和 JuckMock。我的测试方法如下。这个想法不是使用真正的存储库并使用 JustMock 来模拟一个,但是在代码中,我得到了 updatedCustomer 的值并且测试方法失败了。希望有人能指出我正确的方向。

    [TestMethod]
    public void ShouldDeleteCustomerWithIdParam()
    {
        var repo = Mock.Create<ICustomerRepository>();
        var customerService = new CustomerService(repo);
        var customer = Mock.Create<Customer>();            
        customerService.Delete(customer.Id);
        var updatedCustomer = _customerService.Get(customer.Id);
        Assert.IsNull(updatedCustomer, "customer hasn't been deleted");
    }
4

3 回答 3

2

你可以通过两种方式做到这一点。

断言 ICustomerRepository 上的相关方法已被调用。如果它被称为删除,那么这将是:

Mock.Assert(() => repo.Delete(), Occurs.Once());

或者使用假的。创建实现 ICustomerRepository 的 FakeCustomerRepository。实现一个 add 方法以允许添加客户并在您的测试中设置客户。然后删除方法只需要删除该客户。

var repo = new FakeCustomerRepository();
repo.AddCustomer(1);
repo.AddCustomer(2);
var customerService = new CustomerService(repo); 
customerService.Delete(1);
var deletedCustomer = _customerService.Get(1);
Assert.IsNull(updatedCustomer, "customer hasn't been deleted");
于 2014-04-22T14:04:53.510 回答
2

您的测试似乎使用了两个不同CustomerService的 s:一个在测试内部customerService创建,另一个在测试外部创建,_customerService.

除此之外,由于您想模拟存储库,因此仅使用行为验证来断言预期结果会更容易。也就是说,您并不真的想执行删除,然后尝试检索已删除的客户 - 您只想验证customerService在提供的存储库上调用了正确的方法。

例如:

[TestMethod]
public void ShouldDeleteCustomerWithIdParam()
{
    var testID = "A test ID";
    var repo = Mock.Create<ICustomerRepository>();
    var customerService = new CustomerService(repo);
    customerService.Delete(testID);

    Mock.Assert(() => repo.DeleteCustomer(testID), Occurs.AtLeastOnce());
}
于 2014-04-22T14:06:49.140 回答
2

一个简短的答案和一个更长的答案:)

正如@Lilshieste 所指出的,您正在使用两个不同的存储库对象。您的客户对象从其中一个中删除,然后尝试从另一个中检索,可能一开始就没有添加到另一个中。

您可能想再看看您在这里测试的内容。假设CustomerService是一个相当薄的包装CustomerRepository,一旦完成,所有这些测试真正要做的就是运行代码CustomerService.Delete并检查它的调用CustomerRepository.Delete。这个问题有两个方面:

  1. 您正在测试一个类如何完成它的工作,而不是该类做了什么。这将测试与班级结合起来,并要求测试知道CustomerService哪些事情实际上与其无关。

  2. 当此代码在没有模拟的情况下运行时,我假设您正在使用 ORM 或 ADO.NET 从数据存储中实际删除项目 -这是您希望确保有效的行为,但您正在模拟它。有一个测试显示“删除客户有效!” 但实际上并没有测试真正的客户删除代码可能具有欺骗性。

考虑到这一点,我不会说您正在编写的测试实际上对您有很大帮助。我建议将其更改为实际命中您的数据存储并执行真正的删除代码的集成测试。

Jimmy Bogard 在这里写了关于单元测试存储库的文章

于 2014-04-22T14:33:18.877 回答