2010-01-19 2 views
1

Мне было интересно, что я должен проверить и как я должен протестировать IRepository.Тестирование репозитория интерфейса

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

Это то, что мой MemoryRepository выглядит следующим образом:

public class MemoryRepositoryUser : IRepositoryUser 
{ 
    List<User> fakeUsers;  

    public MemoryRepositoryUser(List<User> fakeUsers) 
    { 
     this.fakeUsers = fakeUsers; 
    } 

    public IEnumerable<User> GetAll() 
    { 
     return fakeUsers; 
    } 

    public User GetById(string id) 
    { 
     return GetAll().Where(u => u.Username == id).Single(); 
    } 
} 

Вот некоторые тесты я писал:

[TestFixture] 
class TestMemoryRepositoryUser 
{ 
    private MemoryRepositoryUser repository; 

    public TestMemoryRepositoryUser(){ 
     repository = new MemoryRepositoryUser(FakeData.GetFakeUsers()); 
    } 

    [Test] 
    public void Get_All_Users() 
    { 
     var Users = repository.GetAll(); 
     Assert.IsNotNull(Users); 
     Assert.IsInstanceOf(typeof(IEnumerable<User>), Users); 
     Assert.AreEqual(3, Users.Count()); 
    } 

    [Test] 
    public void Get_User_By_ID() 
    { 
     var Username = "Bob"; 
     var User = repository.GetById(Username); 
     Assert.IsNotNull(User); 
     Assert.AreEqual(Username, User.Username); 
    } 
} 

Я довольно новыми для тестирования кода, и я в основном возникают проблемы с тем, что я должен проверить , Я думаю, что тестирование MemoryRepository помогает мне создавать все функции, которые мне нужны в интерфейсе, без необходимости разговаривать с базой данных?

+0

Duplicate: http://stackoverflow.com/questions/406731/whats-the-point-of-testing-fake-repositories – bzlm

+0

Я не думаю, что это дубликат, это действительно обратный другой вопрос. –

ответ

5

Обычно тесты хранилища являются интеграционными тестами, и они общаются с базой данных. Как вы заметили, нет смысла тестировать репозиторий с поддельными данными.

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

+0

Большое спасибо за ваш ответ. – Pickels

1

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

Рассмотрите, что происходит, когда вы пишите тест Delete_user. Не имеет значения, проходит ли этот тест до Get_All_Users. Я бы новый новый MemoryRepositoryUser в каждом тесте. Этот тестовый запах может существовать в других тестах и ​​не является специфическим, если вы должны проверить подделку или нет.

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

+0

Спасибо, это действительно хорошее предложение. – Pickels

0

Если вы планируете использовать свой MemoryRepositoryUser только как заглушку, чтобы протестировать поведение в клиенте репозитория, тогда я рекомендую вам не тестировать MemoryRepositoryUser сам по себе. Вместо этого сосредоточьте свою энергию на тестировании или тестировании на внедрение производства IRepositoryUser.

С другой стороны, помните, что ваша производственная реализация IRepositoryUser, которую я назову AdoBasedRepositoryUser (для примера, где вы используете ADO), должна вести себя так же, как ваш заглушка. Если нет, тогда тесты для клиента репозитория могут принять неправильное поведение в IRepositoryUser. Вы можете рассмотреть некоторые тесты для этого.

Например, при тестировании AdoBasedRepositoryUser, вы будете проверять GetById(), написав тест, похожий на этот:

 
in AdoBasedRepositoryUserTest... 
[Test] 
GetById_RecordFound() { 
    insert record with ID 762 directly into the USERS table 
    User expected = User with ID 762 and the mandatory properties set 
    User actual = new AdoBasedRepositoryUser().GetById(762); 
    Assert.AreEqual(expected, actual); // Implement User.Equals() to compare the values 
} 

Вы хотите, чтобы убедиться, что MemoryRepositoryUser также проходит этот тест, так что вы можете использовать, чтобы stub IRepositoryUser в тестах для своего клиента.

 
in MemoryRepositoryUserTest... 
[Test] 
GetById_RecordFound() { 
    MemoryRepositoryUser repository = new MemoryRepositoryUser(); 
    User expected = User with ID 762 and the mandatory properties set 
    repository.Add(expected); 
    User actual = repository.GetById(762); 
    Assert.AreEquals(expected, actual); 
} 

Пока у вас есть тесты в MemoryRepositoryUserTest, которые соответствуют тестам в AdoBasedRepositoryUser, то вы знаете, что ваш окурок соответствует поведению производства. Таким образом, вы можете безопасно использовать заглушку при тестировании служб, которые используют этот репозиторий.

После того, как вы сделали это несколько раз, вы можете быть готовы посмотреть Контрактные тесты. (Google it.)

Последнее: я бы назвал ваш интерфейс репозитория IUserRepository вместо IRepositoryUser.

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