Несколько операторов RunWith в jUnit



Я пишу модульный тест и хочу использовать JUnitParamsRunner и MockitoJUnitRunner для одного тестового класса.



к сожалению, не работает:



@RunWith(MockitoJUnitRunner.class)
@RunWith(JUnitParamsRunner.class)
public class DatabaseModelTest {
// some tests
}


есть ли способ использовать оба, Mockito и JUnitParams в одном тестовом классе?

612   6  

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

    Ничего не найдено.