Тестирование интерфейса хранилища - PullRequest
1 голос
/ 19 января 2010

Мне было интересно, что я должен проверить и как я должен проверить 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 поможет мне создать все необходимые мне функции в интерфейсе, не обращаясь к базе данных?

Ответы [ 3 ]

5 голосов
/ 19 января 2010

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

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

1 голос
/ 19 января 2010

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

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

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

0 голосов
/ 20 января 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...