2016-01-22 11 views
1

Я новичок в TDD, и я использую стек XUnit, AutoFixture и Moq. Мне интересно, какая цель moq - когда вы тестируете функцию, которая делает вызов в репозиторий, который попадает в базу данных.Цель использования Moq для разрешения тестовых зависимостей, если запросы IRepository не возвращают значения

Например:
У меня есть простая структура проекта, где мой BLL ссылается мой DAL. В моем обычном приложении IRproository вводится в ProductBLL.cs. Поэтому я вижу, что Moq помогает мне вводить один и тот же репозиторий в мой тест. (Но какой смысл, если функции, которые попали в базу данных не работают?)

Мой вопрос:
Позволяет сказать, что я делаю тесты, чтобы проверить свой бизнес-уровень, и я хочу, чтобы проверить функции, которые вызывают мое репозиторий, который вызывает мою базу данных в моем фактическом коде. Если использование Moq и данные не возвращаются, можно ли тестировать такие функции? В приведенных ниже примерах sut.GetProducts() ничего не возвращает и в моем фактическом коде он попадает в базу данных и что-то возвращает.

Допустим, у меня есть простой тест, который делает это с Moq:

[Fact] 
    public void TestGetProducts_Manual_Moq() 
    { 
     // Arrange 
     var mockCustomerRepository = new Mock<IProductRepository>(); 

     var sut = new ProductBLL(mockProductRepository.Object); 

     // Act 
     var result = sut.GetProducts(); 

     // Assert 
     Assert.True(result.Count > 0); 
    } 

Вот простой тест с использованием AutoFixture в сочетании с Moq на полную катушку: (я думаю, что в этом примере AutoFixture по крайней мере возвращения 3 ряда фиктивных данных)

[Fact] 
    public void TestGetProducts_AutoMoq() 
    { 
     // Arrange 
     Fixture fixture = new Fixture(); 

     // Add auto mocking support for Moq 
     fixture.Customize(new AutoMoqCustomization()); 

     var sut = fixture.Create<ProductBLL>(); 

     // Act 
     var result = sut.GetProducts(); 

     // Assert 
     Assert.True(result.Count > 0); 
    } 

ответ

3

Если GetProducts просто вызывает хранилище и ничего не делать с результатами может быть спорно, если это стоит проверить. Однако вообще GetProducts может делать много других вещей, например: фильтрация, группировка, изменение формата и многое другое.

В этом случае вы можете подтвердить достоверность только в том случае, если GetProducts возвращает некоторые результаты. Например, предположим, что репозиторий возвращает объекты типа A, но GetProducts возвращает объекты типа B. Это означает, что данные должны быть скопированы из объектов типа A в объекты типа B. В этом случае некоторые данные могут быть удалены, некоторые переформатированы и т. Д. Тестирование должно проверить правильность конечного результата.

Во-вторых, GetProducts может использовать 1, 2 или более методов репозитория. Некоторые из этих методов могут использоваться только один раз и несколько раз. Если да, то вы можете использовать макет для проверки, если были использованы методы:

  • правильное количество раз
  • в правильном порядке
  • с правильными значениями параметров

This и this вопросы касаются проверки правильного порядка вызовов методов в Moq. This Вопрос о проверке количества вызовов в Moq. Я также настоятельно рекомендую прочитать учебник this.

+0

Я понимаю, что нет смысла тестировать функцию, которая просто делает простой вызов базы данных. Но, допустим, у меня действительно сложная бизнес-функция, которая имеет несколько вызовов в репозиторий. Как работает тест, если хранилище никогда ничего не возвращает?Поэтому, основываясь на ваших высказываниях, вы не будете тестировать функцию, возвращающую данные. Но это нормально проверить функцию, которая делает вызовы данных внутри нее? –

+0

Поддельные объекты используются не только для имитации реальных объектов (в этом случае они называются заглушками), но и для проверки правильности использования методов (в этом случае они называются mocks). Другими словами, вы должны использовать mock-объект, созданный Moq, чтобы проверить, что вам нужно. –

+0

Как правило, я бы не тестировал функцию в BLL, которая извлекает данные и что-то делает с ними. Я бы тестировал функцию в BLL, которая берет данные в качестве параметра, поэтому я могу использовать AutoFixture для создания фиктивных данных. Имеет ли это смысл? –