Junit / Mockito: выбор запуска теста с пробными или интеграционными тестами - PullRequest
2 голосов
/ 05 июля 2011

Я учу Мокито.Перед тем, как начать использовать фиктивные объекты, у меня было несколько модульных тестов, которые были больше похожи на интеграционные тесты, поэтому у меня был бы тестовый класс с setUpBeforeClass (), например так:

@BeforeClass
public static void setUpBeforeClass() throws Exception {
    instance = new UserDataAccess();
    instance.setDb(new MyDb());
}

Теперь с фиктивным объектомВо многом похоже, но настройка немного сложнее:

@BeforeClass
public static void setupBeforeClass throws Exception {
    instance = new UserDataAccess();
    MyDb myDb = mock(MyDb.class);
    when(...).thenReturn(...);
    ...
    instance.setDb(myDb);
}

Также у меня есть набор тестов, который использовался для загрузки БД в известном состоянии перед запуском тестов, и это делается с первымтестовый класс, вызываемый набором.

Я думаю, что не следует выбрасывать интеграционные тесты, поэтому я подумывал разбить набор тестов на UnitTestSuite и IntegrationTestSuite.На самом деле фиктивные тесты не проверяют все, например, они не проверяют правильность запросов.

Кроме того, единственным различием между этими двумя наборами будет первоначальный сброс БД и setUpBeforeClass ()код.Было бы бесполезно копировать и изменять все тестовые классы только для изменения метода.Первоначальный сброс БД легко пропустить, я просто не включаю класс теста сброса БД в комплект модульных тестов.

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

Или другие подходы?Как ты это делаешь, или что бы ты делал?

Ответы [ 2 ]

9 голосов
/ 05 июля 2011

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

Интеграция с другимрука, имеет другой акцент.Речь идет о том, чтобы все ваши классы работали вместе для достижения желаемого результата.Так что имейте это в виду, когда кодируете их.Это большая картина, которую вы ищете.Вам не нужно беспокоиться о крайних случаях отдельных классов, потому что это работа ваших проверенных модульных тестов.Но такие вещи, как состояние базы данных, именно поэтому важны интеграционные тесты.

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

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

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

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

0 голосов
/ 05 июля 2011

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

Для модульного теста я предполагаю, что вы используете базу данных в качестве заглушки для предоставления некоторых данных в тестах и ​​в качествеиздеваться, когда ваш тест вызывает что-то вроде saveMyDomainObject().В первом случае вы можете смоделировать только то, что вам действительно нужно для конкретного теста, а не всю настройку базы данных.Во втором случае вы должны использовать Mockito validate, чтобы проверить правильность ожидаемого поведения.

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