Несколько операторов 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

Ответ 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
}