Как вы издеваетесь над своими хранилищами?

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

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

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

11.12.2008 15:08:53
3 ОТВЕТА
РЕШЕНИЕ

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

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

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

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

6
11.12.2008 15:23:39

Я предполагаю, что под «хранилищем» вы подразумеваете 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;
    }
}
0
11.12.2008 15:22:01
Я имею в виду шаблон хранилища. Я отредактировал вопрос со ссылкой на определение Мартина Фаулера.
Mike Scott 11.12.2008 15:32:50

SCNR:

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

6
11.12.2008 15:36:33
Это первое, о чем я подумал, когда прочитал вопрос :-)
Ferruccio 11.12.2008 16:48:34
Спасибо за этот ответ. Это спасло меня от усилий.
Mark Meuer 11.12.2008 17:07:01