Несколько операторов RunWith в jUnit
Я пишу модульный тест и хочу использовать JUnitParamsRunner и MockitoJUnitRunner для одного тестового класса.
к сожалению, не работает:
@RunWith(MockitoJUnitRunner.class)
@RunWith(JUnitParamsRunner.class)
public class DatabaseModelTest {
// some tests
}
есть ли способ использовать оба, Mockito и JUnitParams в одном тестовом классе?
6 ответов:
вы не можете сделать это, потому что в соответствии со спецификацией вы не можете поместить одну и ту же аннотацию дважды на один и тот же аннотированный элемент.
Итак, каково же решение? Решил поставить только один
@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 = new MockitoRule();и вы можете запустить этот тестовый случай с любым бегуном вы хотите.
начиная с JUnit 4.7 и Mockito 1.10.17, эта функциональность встроена; есть
org.mockito.junit.MockitoRuleкласса. Вы можете просто импортировать его и добавить строку@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();на ваш тестовый класс.
это решение работает для каждого возможного бегуна, а не только для этого примера mockito. Например; для Spring просто измените классы runner и добавьте необходимые аннотации.
@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). Этот метод гарантирует, что основной бегун запускается правильно перед запуском sub runner, эффективно реализуя несколько вложенных@RunWithаннотации с зависимыми тестовыми классами.также на https://bekce.github.io/junit-multiple-runwith-dependent-tests
в моем случае я пытался высмеять какой-то метод в spring bean и
MockitoAnnotations.initMocks(test);не работает. Вместо этого вы должны определить, что Боб построен с использованием метода mock внутри вашего xml-файла, как показано ниже.
... <bean id="classWantedToBeMocked" class="org.mockito.Mockito" factory-method="mock"> <constructor-arg value="com.fullpath.ClassWantedToBeMocked" /> </bean> ...и добавьте этот боб с autowired внутри вашего тестового класса, как показано ниже.
@RunWith(SpringJUnit4ClassRunner.class) @ContextConfiguration(locations="file:springconfig.xml") public class TestClass { ... @Autowired private ClassWantedToBeMocked classWantedToBeMocked; ... when(classWantedToBeMocked.methodWantedToBeMocked()).thenReturn(...); ... }
С момента выхода 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/
вы также можете попробовать это:
@RunWith(JUnitParamsRunner.class) public class AbstractTestClass { // some tests } @RunWith(MockitoJUnitRunner.class) public class DatabaseModelTest extends AbstractTestClass { // some tests }
Comments