Несколько операторов RunWith в jUnit
Я пишу unit test и хочу использовать JUnitParamsRunner
и MockitoJUnitRunner
для одного тестового класса.
К сожалению, следующее не работает:
@RunWith(MockitoJUnitRunner.class)
@RunWith(JUnitParamsRunner.class)
public class DatabaseModelTest {
// some tests
}
Есть ли способ использовать как Mockito, так и JUnitParams в одном тестовом классе?
Ответы
Ответ 1
Вы не можете сделать это, потому что согласно спецификации вы не можете поместить одну и ту же аннотацию дважды в один и тот же аннотированный элемент.
Итак, каково решение? Решение состоит в том, чтобы поместить только один @RunWith()
с бегуном, без которого вы не можете стоять, и заменить другой чем-то другим. В вашем случае, я думаю, вы удалите MockitoJUnitRunner
и сделаете то, что он делает, программно.
Фактически единственное, что он делает, это работает:
MockitoAnnotations.initMocks(test);
в начале теста. Итак, самое простое решение - поместить этот код в setUp()
:
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
Я не уверен, но, вероятно, вам следует избегать многократного вызова этого метода с использованием флага:
private boolean mockInitialized = false;
@Before
public void setUp() {
if (!mockInitialized) {
MockitoAnnotations.initMocks(this);
mockInitialized = true;
}
}
Однако лучше, многократно используемое решение может быть реализовано с помощью правил JUnt.
public class MockitoRule extends TestWatcher {
private boolean mockInitialized = false;
@Override
protected void starting(Description d) {
if (!mockInitialized) {
MockitoAnnotations.initMocks(this);
mockInitialized = true;
}
}
}
Теперь просто добавьте следующую строку в ваш тестовый класс:
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
и вы можете запустить этот тестовый случай с любым бегуном, который вы хотите.
Ответ 2
Как и в JUnit 4.7 и Mockito 1.10.17, эта функция встроена; существует класс org.mockito.junit.MockitoRule
. Вы можете просто импортировать его и добавить строку
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
для вашего тестового класса.
Ответ 3
Это решение работает для всех возможных участников, а не только для этого примера. Например; для Spring просто измените классы бегунов и добавьте необходимые аннотации.
@RunWith(JUnitParamsRunner.class)
public class DatabaseModelTest {
@Test
public void subRunner() throws Exception {
JUnitCore.runClasses(TestMockitoJUnitRunner.class);
}
@RunWith(MockitoJUnitRunner.class)
public static class TestMockitoJUnitRunner {
}
}
DatabaseModelTest
будет выполняться JUnit. TestMockitoJUnitRunner
зависит от него (по логике), и он будет запускаться внутри основного в методе @Test
во время вызова JUnitCore.runClasses(TestMockitoJUnitRunner.class)
. Этот метод обеспечивает правильный static class TestMockitoJUnitRunner
запуска перед static class TestMockitoJUnitRunner
, эффективно реализуя несколько вложенных аннотаций @RunWith
с зависимыми классами тестирования.
Также на https://bekce.github.io/junit-multiple-runwith-dependent-tests
Ответ 4
Начиная с выпуска PowerMock 1.6, вы можете сделать это так же легко, как
@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(JUnitParamsRunner.class)
public class DatabaseModelTest {
// some tests
}
Объясняется здесь https://blog.jayway.com/2014/11/29/using-another-junit-runner-with-powermock/
Ответ 5
В моем случае я пытался выполнить какой-либо метод в spring bean и
MockitoAnnotations.initMocks(test);
не работает. Вместо этого вы должны определить, что bean построено с использованием метода mock внутри вашего XML файла, как показано ниже.
...
<bean id="classWantedToBeMocked" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="com.fullpath.ClassWantedToBeMocked" />
</bean>
...
и добавьте, что bean с autwired внутри вашего тестового класса, как показано ниже.
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="file:springconfig.xml")
public class TestClass {
...
@Autowired
private ClassWantedToBeMocked classWantedToBeMocked;
...
when(classWantedToBeMocked.methodWantedToBeMocked()).thenReturn(...);
...
}
Ответ 6
проверить эту ссылку https://bekce.github.io/junit-multiple-runwith-dependent-tests/, используя этот подход, я объединил @RunWith (Parameterized.class) - внешний бегун - с @RunWith (MockitoJUnitRunner.class) - внутренний бегун. Единственный трюк, который я должен был добавить, состоял в том, чтобы сделать мои переменные-члены во внешнем классе/бегуне статическими, чтобы сделать их доступными для внутреннего/вложенного бегуна/класса. удачи и наслаждайтесь.
Ответ 7
Вы также можете попробовать следующее:
@RunWith(JUnitParamsRunner.class)
public class AbstractTestClass {
// some tests
}
@RunWith(MockitoJUnitRunner.class)
public class DatabaseModelTest extends AbstractTestClass {
// some tests
}