JUnit: использование конструктора вместо @Before
Я использую JUnit 4. Я не вижу разницы между инициализацией в конструкторе или с помощью специальной функции init аннотируются @Before
. Значит ли это, что мне не нужно беспокоиться об этом?
есть ли случай, когда @Before
дает больше, чем просто инициализация в конструкторе?
8 ответов:
нет, использование конструктора для инициализации вашего тестового устройства JUnit технически равно использованию
@Before
метод (из-за того, что JUnit создает новый экземпляр класса тестирования для каждого@Test
). Единственное (коннотационное) различие заключается в том, что оно нарушает симметрию между@Before
и@After
, что может быть запутанным для некоторых. ИМХО лучше придерживаться условностей (которые использует@Before
).обратите внимание также, что до JUnit 4 и аннотаций были посвящается
setUp()
иtearDown()
методы -@Before
и@After
аннотации заменяют их, но сохраняют основную логику. Таким образом, использование аннотаций также упрощает жизнь для тех, кто мигрирует из JUnit 3 или более ранних версий.заметные различия
Подробнее из комментариев:
@Before
позволяет переопределять поведение родительского класса, конструкторы заставляют вас вызывать конструкторы родительского класса- конструктор работает до конструкторы подклассов и
@Rule
методы@Before
работает после все- исключения в
@Before
причина@After
вызываемые методы, исключения в конструкторе не
@Before имеет больше смысла использовать в некоторых случаях, потому что он вызывается после конструктора для класса. Это различие важно, когда вы используете макет структуры, такой как Mockito с аннотациями @Mock, потому что ваш метод @Before будет вызван после инициализации mocks. Затем вы можете использовать свои насмешки для предоставления аргументов конструктора тестируемому классу.
Я считаю, что это очень распространенный шаблон в моих модульных тестах при использовании совместной работы зернышки.
вот пример (правда надуманный) пример:
@RunWith(MockitoJUnitRunner.class) public class CalculatorTest { @Mock Adder adder; @Mock Subtractor subtractor; @Mock Divider divider; @Mock Multiplier multiplier; Calculator calculator; @Before public void setUp() { calculator = new Calculator(adder,subtractor,divider,multiplier); } @Test public void testAdd() { BigDecimal value = calculator.add(2,2); verify(adder).add(eq(2),eq(2)); } }
Я предпочитаю объявлять свои светильники как окончательные и инициализировать их в строке или в конструкторе, поэтому я не забываю их инициализировать! Однако, поскольку исключения, брошенные в @Before, обрабатываются более удобным для пользователя способом, я обычно инициализирую тестируемый объект в @Before.
Я предпочитаю использовать конструкторы для инициализации мой тест-объектов, потому что это позволяет мне сделать все члены
final
Так что IDE или компилятор скажет мне, когда конструктор забыл инициализировать элемент и предотвратить их установку другим методом.ИМХО,
@Before
нарушает одно из самых важных соглашений Java, которое полагается на конструктор для полной инициализации объектов!
@Before вызывается перед любым @Test не только один раз за тестовый класс.
Это может быть использовано для сброса / инициализации данных для каждого конкретного теста (например, сброс переменных до определенного значения и т. д.).таким же образом @After можно использовать для очистки кода после выполнения метода @Test.
см.:http://junit.sourceforge.net/javadoc/org/junit/Before.html
есть одна вещь, которая конструктор можно архивировать, но не @перед.
вы должны использовать конструктор, когда вам нужно исходные поля, определенные в родительском классе. Например:
abstract class AbstractIT { int fieldAssignedInSubClass; public AbstractIT(int fieldAssignedInSubClass) { this.fieldAssignedInSubClass= fieldAssignedInSubClass; } @Before void before() { // comsume fieldAssignedInSubClass } } public class ChildIT extends AbstractIT{ public ChildIT() { // assign fieldAssignedInSubClass by constructor super(5566); } @Before void before() { // you cannot assign fieldAssignedInSubClass by a @Before method } }