как провести модульное тестирование метода удаления с помощью JustMock lite и MSTest?

Я только начинаю заниматься модульным тестированием и теперь застрял в написании тестового метода для удаления. Я использую 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");
    }

person lawphotog    schedule 22.04.2014    source источник


Ответы (3)


Короткий ответ и более длинный :)

Как указал @Lilshieste, вы работаете с двумя разными объектами репозитория. Ваш объект клиента удаляется из одного из них, а затем пытается быть извлечен из другого, возможно, даже не добавляясь к другому.

Вы можете еще раз взглянуть на то, что вы тестируете здесь. Предполагая, что CustomerService является довольно тонкой оболочкой вокруг CustomerRepository, все, что этот тест действительно сделал бы после его завершения, — это прогнал код через CustomerService.Delete и проверил, вызывает ли он CustomerRepository.Delete. Проблема с этим двоякая:

  1. Вы проверяете как класс выполняет свою работу, а не что он делает. Это связывает тест с классом и требует, чтобы тест знал что-то о CustomerService, что на самом деле не его дело.

  2. Когда этот код работает без макета, я предполагаю, что вы используете ORM или ADO.NET для фактического удаления элемента из вашего хранилища данных — это поведение, которое вы хотите, чтобы оно работало, но вы повторно высмеивать его. Имея тест, который говорит: «Удаление клиентов работает!» но который на самом деле не проверяет реальный код удаления клиента, может быть обманчивым.

Имея это в виду, я бы не сказал, что тест, который вы пишете, на самом деле покупает вас очень много. Я бы порекомендовал изменить его на тест интеграции, который действительно обращается к вашему хранилищу данных и проверяет реальный код удаления.

Джимми Богард написал о репозиториях модульного тестирования здесь.

person Steve Wilkes    schedule 22.04.2014
comment
_customerRepository — это просто опечатка. Изменение этого не помогает. Однако ваше объяснение помогло мне лучше понять тестирование. Спасибо. - person lawphotog; 22.04.2014

Вы можете сделать это двумя способами.

Подтвердите, что был вызван соответствующий метод в ICustomerRepository. Если бы это называлось Удалить, то это было бы:

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

Или использовать подделку. Создайте FakeCustomerRepository, реализующий ICustomerRepository. Реализуйте метод добавления, чтобы разрешить добавление клиентов, и в своем тесте настройте в нем клиентов. Затем метод удаления просто должен удалить этого клиента.

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");
person Andy Nichols    schedule 22.04.2014

В вашем тесте используются два разных CustomerService: один создан внутри теста, 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());
}
person Lilshieste    schedule 22.04.2014