简体   繁体   English

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

[英]how to unit test a delete method using JustMock lite and MSTest?

I am just getting started with unit testing and now stuck writing a test method for delete. 我刚刚开始进行单元测试,现在却坚持编写删除的测试方法。 I am using MStest and JuckMock. 我正在使用MStest和JuckMock。 I have my test method as follow. 我的测试方法如下。 The idea is not to use real repository and use JustMock to mock one but in the code, i am getting a value for updatedCustomer and the test method failed. 这个想法不是使用真实的存储库,而是使用JustMock模拟一个存储库,但是在代码中,我获取了一个updatedCustomer的值,并且测试方法失败了。 Hope someone can point out me the right direction. 希望有人能指出正确的方向。

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

You could do it in two ways. 您可以通过两种方式做到这一点。

Assert that the relevant method on ICustomerRepository has been called. 断言已调用ICustomerRepository上的相关方法。 If it was called Delete then this would be: 如果将其称为“删除”,则将为:

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

Or use a fake. 或使用假货。 Create FakeCustomerRepository implementing ICustomerRepository. 创建实现ICustomerRepository的FakeCustomerRepository。 Implement an add method to allow customers to be added and in your test set up customers in it. 实现添加方法以允许添加客户,并在您的测试中设置客户。 The delete method then just needs to remove that customer. 然后,删除方法仅需要删除该客户。

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

Your test appears to be using two different CustomerService s: one created inside the test, customerService , and another created outside the test, _customerService . 您的测试似乎使用了两种不同的CustomerService :一种是测试内部创建的,是customerService ,另一种是在测试外部创建的_customerService

Aside from that, since you want to mock out the repository it would be easier to just use behavior verification to assert the expected result. 除此之外,由于您要模拟存储库,因此仅使用行为验证来声明预期结果会更容易。 That is, you don't really want to perform a delete, and then try to retrieve the deleted customer - you just want to verify that customerService invokes the correct method on the supplied repository. 也就是说,您实际上并不想执行删除操作,然后尝试检索已删除的客户-您只想验证customerService在提供的存储库上调用了正确的方法。

For example: 例如:

[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());
}

A short answer and a longer one :) 一个简短的答案和一个更长的答案:)

As pointed out by @Lilshieste, you're working with two different repository objects. 正如@Lilshieste指出的那样,您正在使用两个不同的存储库对象。 Your customer object is deleted from one of them and then attempted to be retrieved from the other, possibly without ever being added to the other in the first place. 您的客户对象从其中一个对象中删除,然后尝试从另一个对象中检索,这可能根本就没有添加到另一个对象中。

You may want to take another look at what you're testing here. 您可能想再看看您在这里进行的测试。 Assuming CustomerService is a fairly thin wrapper around CustomerRepository , all this test would really do once it was complete is run code through CustomerService.Delete and check it calls CustomerRepository.Delete . 假设CustomerService是围绕CustomerRepository的相当薄的包装,则此测试一旦完成就将真正完成的全部工作是通过CustomerService.Delete运行代码并检查其是否调用CustomerRepository.Delete The problem with this is two-fold: 这个问题有两个方面:

  1. You're testing how a class does it's job, not what the class does. 您正在测试一类是怎么做的工作,而不是类做什么 This couples the test to the class and requires the test to know things about CustomerService which are really none of its business. 这将测试与类耦合在一起,并要求测试了解与CustomerService无关的事情。

  2. When this code runs without a mock, I assume you're using an ORM or ADO.NET to actually delete an item from your data store - that's the behaviour you want to be sure works, but you're mocking it out. 当此代码在没有模拟的情况下运行时,我假设您正在使用ORM或ADO.NET从数据存储中实际删除某项- 这是您希望确保可以正常运行的行为,但是您正在模拟该行为。 Having a test which says "Deleting Customers works!" 有一个测试说“删除客户有效!” but which doesn't actually test the real customer deletion code could be deceptive. 但实际上并未测试真实的客户删除代码可能具有欺骗性。

With this in mind, I wouldn't say the test you're writing actually buys you very much. 考虑到这一点,我不会说您正在编写的测试实际上会给您带来很多好处。 I'd recommend changing it to an integration test which actually hits your data store and exercises the real delete code. 我建议将其更改为一个集成测试,该测试实际上会命中您的数据存储并执行实际的删除代码。

Jimmy Bogard's written about unit testing repositories here . 吉米·博加德(Jimmy Bogard) 在此处撰写了有关单元测试存储库的文章。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM