Требуется помощь / совет с репозиториями модульного тестирования - PullRequest
2 голосов
/ 09 декабря 2010

Я использую макеты .NET 4, NUnit и Rhino.Я хочу протестировать мой репозиторий новостей, но я не уверен, как это сделать.Мой репозиторий новостей - это то, что я в конечном итоге буду использовать для связи с базой данных.Я хочу использовать его для проверки поддельных / фиктивных данных.Не уверен, если это возможно?Вот что у меня сейчас:

public interface INewsRepository
{
   IEnumerable<News> FindAll();
}

public class NewsRepository : INewsRepository
{
   private readonly INewsRepository newsRepository;

   public NewsRepository(INewsRepository newsRepository)
   {
      this.newsRepository = newsRepository;
   }

   public IEnumerable<News> FindAll()
   {
      return null;
   }
}

Мой модульный тест выглядит следующим образом:

public class NewsRepositoryTest
{
   private INewsRepository newsRepository;

   [SetUp]
   public void Init()
   {
      newsRepository = MockRepository.GenerateMock<NewsRepository>();
   }

   [Test]
   public void FindAll_should_return_correct_news()
   {
      // Arrange
      List<News> newsList = new List<News>();
      newsList.Add(new News { Id = 1, Title = "Test Title 1" });
      newsList.Add(new News { Id = 2, Title = "Test Title 2" });

      newsRepository.Stub(r => r.FindAll()).Return(newsList);

      // Act
      var actual = newsRepository.FindAll();

      // Assert
      Assert.AreEqual(2, actual.Count());
   }
}

В приведенном выше коде я не уверен, что мне нужно издеваться.Приведенный выше код компилируется, но в графическом интерфейсе NUnit происходит сбой в отношении значения конструктора.Я могу только предположить, что это связано с параметром INewsRepository, который мне нужно предоставить NewsRepository.Я не знаю, как это сделать в тесте.Может кто-нибудь исправить мой модульный тест, чтобы он прошел в графическом интерфейсе NUnit?Может ли кто-нибудь также высказать свое мнение о том, правильно ли я внедряю свои репозитории?

Будучи новичком в издевательствах, есть ли что-то, что мне нужно проверить?Когда мне нужно будет проверить?Какова его цель?Я работал над несколькими проектами с исходным кодом, и некоторые из них используют проверку, а некоторые - нет.

Если вышеуказанный тест пройден, что это доказывает мне как разработчику?Что другой разработчик должен сделать с моим хранилищем, чтобы он не работал в графическом интерфейсе NUnit?

Извините за все вопросы, но это вопросы новичка:)

Надеюсь, что-то может мне помочьиз.

Ответы [ 3 ]

5 голосов
/ 09 декабря 2010

Как сказал Стивен, вы Assert против Mock NewsRepository в приведенном выше коде.

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

. Вы используете репозиторий Mock NewsRepository для проверки чего-то, что использует INewsRepository, в вашем случае вы упоминаете NewsService;NewsService будет использовать ваш макет INewsRepository.

Если вы ищете в своем решении что-либо, использующее INewsRepository.FindAll (), вы создадите репозиторий Mock для тестирования этого кода изолированно.

Если вы хотите протестировать что-то, что вызывает ваш уровень Service, вам нужно будет смоделировать NewsService.

Кроме того, как сказал Стивен, для NewsRepository не нужно иметь копиюсам вводится IoC, поэтому:

public class NewsRepository : INewsRepository
{
   private readonly INewsRepository newsRepository;

   public NewsRepository(INewsRepository newsRepository)
   {
      this.newsRepository = newsRepository;
   }

   public IEnumerable<News> FindAll()
   {
      return null;
   }
}

должно стать:

public class NewsRepository : INewsRepository
{
   public IEnumerable<News> FindAll()
   {
      return null;
   }
}

Если у вас есть функциональность в вашем методе FindAll (), который требует тестирования, вы можете смоделировать объектычто они используют .

В качестве точки стиля из великого Art Of Unit Testing инициализация фиктивных объектов лучше всего исключать из метода Setup и выполнять вспомогательным методомвызывается в начале метода.Поскольку вызов программы установки будет невидимым и сделает инициализацию макета неясной.

В качестве еще одной точки стиля из этой книги предлагается следующее соглашение об именовании модульных тестов: " MethodUnderTest_Scenario_ExpectedBehavior ",Таким образом,

FindAll_should_return_correct_news
может стать, например:
FindAll_AfterAddingTwoNewsItems_ReturnsACollectionWithCountOf2

Надеюсь, это сделает подход более понятным.

2 голосов
/ 09 декабря 2010

Ваш FindAll_should_return_correct_news метод тестирования не тестирует репозиторий, а сам тестирует. Вы можете увидеть это, когда упростите это до того, что оно действительно делает:

[Test]
public void FindAll_should_return_correct_news()
{
   // Arrange
   List<News> newsList = new List<News>();
   newsList.Add(new News { Id = 1, Title = "Test Title 1" });
   newsList.Add(new News { Id = 2, Title = "Test Title 2" });

   // Act
   var actual = newsList;

   // Assert
   Assert.AreEqual(2, actual.Count());
}

Как видите, в основном вы создаете список, заполняете его и проверяете, действительно ли он содержит количество записей, которые вы в него вставили.

Когда ваш репозиторий не делает ничего, кроме взаимодействия с базой данных (то есть без логики приложения), тестировать с помощью модульного теста нечего. Вы можете решить эту проблему, написав интеграционные тесты для репозиториев. Что в основном можно сделать с помощью такого интеграционного теста, так это вставить несколько записей в тестовую базу данных (хотя использовать реальную базу данных, а не базу данных в памяти), а затем вызвать реальный класс репозитория, чтобы узнать, получает ли он ожидаемые записи из вашего теста. база данных. Все должно быть выполнено в рамках транзакции и откатано в конце теста (это гарантирует, что эти тесты останутся заслуживающими доверия).

Когда вы используете инструмент O / RM, который позволяет вам писать запросы LINQ, вы также можете попробовать другой подход. Вы можете подделать своего поставщика LINQ, как вы можете видеть в этой статье .

1 голос
/ 09 декабря 2010

Возможно, захотите прочитать более это сообщение от ayende

...