2010-12-09 3 views
2

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

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?

Извините за все вопросы, но они являются новичку вопросы :)

Я надеюсь, что soomeone может помочь мне.

+0

Могу ли я видеть не так ли? У NewsRepository есть то же самое на себе? – Aliostad 2010-12-09 13:36:29

+0

@Aliostad: Что ты имеешь в виду? – 2010-12-09 13:39:15

ответ

5

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

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

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

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

Если вы хотите протестировать что-то, что называет ваш уровень обслуживания, вам нужно будет высмеять 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

Ваш тестовый метод 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, как вы можете видеть в this article.

Смежные вопросы