Почему переменные поля становятся нулевыми после установки их в методе JUnitParams?
Я пишу тестовый класс, используя JUnitParams
а также Mockito
, Я хочу использовать Mockito mock
как parameter
, В моем тесте у меня есть около десяти макетов, и я хочу передать только один макет, чтобы определить для него особое поведение.
Я воспроизвел проблему в простом примере.
Моя проблема: я инициализирую переменную myList
в методе parametersForTest
, но когда я отлаживаю в test
метод myList
является нулевым, но param
мой желанный макет.
@RunWith(JUnitParamsRunner.class)
public class MockitoJUnitParamsTest {
private List myList;
@Test
@Parameters
public void test(List param) {
assertThat(param).isEqualTo(this.myList);
}
public Object[] parametersForTest() {
myList = Mockito.mock(List.class);
return new Object[]{myList};
}
}
я использую
- JUnitParams версия 1.0.5
- JUnit версия 4.12
- Mockito версия 1.10.19
Почему myList пуст и как я могу это исправить?
2 ответа
Экземпляр класса MockitoJUnitParamsTest, в котором выполняется метод parametersForTest(), - это не то же самое, что и test(). Это потому, что Junit создаст разные экземпляры для каждого метода тестирования. В вашем случае, сделать myList статическим
private static List myList;
может решить проблему частично, но может не работать, если тесты выполняются параллельно.
Каркасы и бегуны JUnit часто создают отдельные экземпляры тестового класса для каждого вызова метода. Похоже, это то, что делает JUnitParams - вы можете увидеть это с помощью следующего теста:
@RunWith(JUnitParamsRunner.class)
public class JUnitParamsTest {
@Test
@Parameters
public void test(JUnitParamsTest param) {
Assert.assertNotNull(param);
Assert.assertNotSame(this, param);
}
Object[] parametersForTest() {
return new Object[]{this};
}
}
Итак, проблема с вашим примером выше состоит в том, что myList
поле устанавливается parametersForTest
является членом другого объекта от того, который test(List)
вызывается.
Как исправить
Ну, я думаю, ключевой вопрос в том, чего ты здесь пытаешься достичь? Весь смысл JUnitParams в том, что параметры вводятся в методы тестирования, поэтому вам не нужно использовать поля. Мне кажется, что изменение значений полей внутри parametersForTest()
Метод выходит за рамки предполагаемого использования, и я не могу понять, почему вы хотите это сделать.
Одно быстрое и грязное решение было бы сделать myList
static, которое должно работать до тех пор, пока к вашему тестовому классу не будут обращаться одновременно несколько потоков (некоторые среды модульных тестов работают многопоточно, поэтому здесь есть риск).
Лучшим решением было бы изменить дизайн ваших тестов, чтобы вы не модифицировали поля внутри методов генерации параметров. Пример, который вы привели, похоже, не пытается протестировать что-либо кроме самого JUnitParams, поэтому я не могу помочь вам определить, каким будет хороший дизайн, так как я не знаю, чего вы пытаетесь достичь. Вы хотите сказать, что вы хотите, чтобы несколько методов тестирования использовали один и тот же макет Mockito? Если так, то почему? Я не уверен, что Мокито поддержит это (я не пробовал). Модульные тесты, как правило, должны быть изолированы друг от друга, поэтому рекомендуемое действие - каждый раз создавать новый макет.