Как вы издеваетесь над своими хранилищами? - PullRequest
8 голосов
/ 11 декабря 2008

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

Каковы плюсы и минусы каждого подхода?

Редактировать: уточнено значение хранилища со ссылкой на Фаулера.

Ответы [ 3 ]

6 голосов
/ 11 декабря 2008

Я обычно вижу два сценария с репозиториями. Я прошу что-то, и я получаю это, или я спрашиваю что-то, и его там нет.

Если вы издеваетесь над своим репозиторием, это означает, что ваша тестируемая система (SUT) - это то, что использует ваш репозиторий. Таким образом, вы обычно хотите проверить, что ваше SUT ведет себя правильно, когда ему дается объект из хранилища. И вы также хотите проверить, правильно ли он справляется с ситуацией, когда вы ожидаете получить что-то назад, а не хотите или не уверены, что собираетесь что-то вернуть.

Жесткие двойные тесты в порядке, если вы проводите интеграционное тестирование. Скажем, вы хотите сохранить объект, а затем вернуть его обратно. Но это тестирование взаимодействия двух объектов, а не только поведения SUT. Это две разные вещи. Если вы начнете кодировать поддельные репозитории, вам также понадобятся модульные тесты, иначе вы в конечном итоге будете основывать успех и провал вашего кода на непроверенном коде.

Это мое мнение о насмешливых против тестовых двойниках.

6 голосов
/ 11 декабря 2008

SCNR:

«Вы называете себя хранилищем? Я видел спичечные коробки с большей вместимостью!»

0 голосов
/ 11 декабря 2008

Я предполагаю, что под "хранилищем" вы подразумеваете DAO ; если нет, то этот ответ не будет применяться.

В последнее время я делаю "в памяти" "макетные" (или тестовые) реализации моего DAO, которые в основном работают с данными (списком, картой и т. Д.), Переданными в конструктор макета. Таким образом, класс модульных тестов может свободно добавлять любые данные, необходимые для теста, может изменять их и т. Д., Не заставляя все модульные тесты, работающие на DAO «в памяти», кодироваться для использования одних и тех же тестовых данных.

Один плюс, который я вижу в этом подходе, состоит в том, что если у меня есть дюжина модульных тестов, которым нужно использовать один и тот же DAO для своего теста (например, для внедрения в тестируемый класс), мне не нужно запоминать все детали тестовых данных каждый раз (как если бы «макет» был жестко закодирован) - модульный тест создает сами тестовые данные. С другой стороны, это означает, что каждый модульный тест должен тратить несколько строк, создавая и связывая свои тестовые данные; но это маленький недостаток для меня.

Пример кода:

public interface UserDao {
    User getUser(int userid);
    User getUser(String login);
}

public class InMemoryUserDao implements UserDao {

    private List users;

    public InMemoryUserDao(List users) {
        this.users = users;
    }

    public User getUser(int userid) {
        for (Iterator it = users.iterator(); it.hasNext();) {
            User user = (User) it.next();
            if (userid == user.getId()) {
                return user;
            }
        }

        return null;
    }

    public User getUser(String login) {
        for (Iterator it = users.iterator(); it.hasNext();) {
            User user = (User) it.next();
            if (login.equals(user.getLogin())) {
                return user;
            }
        }

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