如何使用JustMock lite和MSTest对删除方法进行单元测试?

时间:2014-04-22 13:46:04

标签: c# unit-testing mstest justmock

我刚刚开始进行单元测试,现在卡住了一个删除测试方法。我正在使用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");
    }

3 个答案:

答案 0 :(得分:2)

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

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

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

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

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");

答案 1 :(得分:2)

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

除此之外,由于您想要模拟存储库,因此使用behavior verification来断言预期结果会更容易。也就是说,您真的不想执行删除,然后尝试检索已删除的客户 - 您只想验证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());
}

答案 2 :(得分:2)

简短答案和较长答案:)

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

您可能想再看一下您在这里测试的内容。假设CustomerServiceCustomerRepository周围的一个相当薄的包装器,所有这个测试真的会在完成后通过CustomerService.Delete运行代码并检查它调用CustomerRepository.Delete。这个问题有两个方面:

  1. 您正在测试 类如何完成它的工作,而不是该类的。这将测试与课程相结合,并要求测试了解CustomerService的事情,而这些事情实际上与其无关。

  2. 当此代码在没有模拟的情况下运行时,我假设您正在使用ORM或ADO.NET实际删除数据存储中的项目 - 您想要的行为确实有效,但你是在嘲笑它。进行一项测试,说“删除客户工作!”但实际上并没有测试真正的客户删除代码可能具有欺骗性。

  3. 考虑到这一点,我不会说你写的测试实际上是非常买的。我建议将其更改为集成测试,该测试实际上会访问您的数据存储并执行真正的删除代码。

    Jimmy Bogard关于单元测试存储库here的文章。