JUnit 中的多个 RunWith 语句

我编写单元测试,并希望对一个测试类使用 JUnitParamsRunnerMockitoJUnitRunner

不幸的是,以下方法并不奏效:

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

有没有办法在一个测试类中同时使用 Mockito 和 JUnitParams?

80931 次浏览

您不能这样做,因为根据 spec,您不能将相同的注释放在同一个带注释的元素上两次。

那么,解决办法是什么?解决的办法是只放一个 @RunWith()与运动员,你不能站没有,并取代其他与别的东西。在您的情况下,我想您将删除 MockitoJUnitRunner,并以编程方式执行它所做的工作。

事实上,它唯一能做的就是:

MockitoAnnotations.initMocks(test);

in the beginning of test case. So, the simplest solution is to put this code into setUp() method:

@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();

你可以用任何你想要的运行器运行这个测试用例。

在 JUnit 4.7和 Mockito 1.10.17中,这个功能是内置的; 有一个 org.mockito.junit.MockitoRule类。您可以简单地导入它并添加该行

@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();

去你的测试班。

你也可以试试这个:

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


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

在我的情况下,我试图嘲笑一些方法在春天的豆子和

MockitoAnnotations.initMocks(test);

相反,您必须在 xml 文件中使用 mock 方法定义要构造的 bean,如下所示。

...
<bean id="classWantedToBeMocked" class="org.mockito.Mockito" factory-method="mock">
<constructor-arg value="com.fullpath.ClassWantedToBeMocked" />
</bean>
...

并在测试类中添加具有自动连接的 bean,如下所示。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="file:springconfig.xml")
public class TestClass {
...
@Autowired
private ClassWantedToBeMocked classWantedToBeMocked;
...
when(classWantedToBeMocked.methodWantedToBeMocked()).thenReturn(...);
...
}

这个解决方案适用于每一个可能的运动员,而不仅仅是这个模仿的例子。例如,对于 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依赖于它(通过逻辑) ,在 JUnitCore.runClasses(TestMockitoJUnitRunner.class)调用期间,它将在 @Test方法中运行 main 的 inside。此方法确保在 static class TestMockitoJUnitRunner子运行程序运行之前正确启动主运行程序,有效地实现具有相关测试类的多个嵌套 @RunWith注释。

也在 https://bekce.github.io/junit-multiple-runwith-dependent-tests频道

Since the release of PowerMock 1.6, you can do it as easily as

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

这里解释 https://blog.jayway.com/2014/11/29/using-another-junit-runner-with-powermock/

点击这里查看链接 < a href = “ https://bekce.github.io/junit-multi-runwith- 依赖性測試/”rel = “ nofollow norefrer”> https://bekce.github.io/junit-multiple-runwith-dependent-tests/ 使用这种方法,我组合了@RunWith (Parameter terized.class)——外部运行器——和@RunWith (MockitoJUnitRunner.class)——内部运行器。我必须添加的唯一调整是使我的成员变量在外部类/运行程序中是静态的,以便使它们对内部/嵌套运行程序/类可访问。祝你好运,好好享受。

我想同时运行 跑步者Org.junit.runner 参数化,我有参数测试,当 SWT 测试失败时我想截屏(截屏功能是由 跑步者提供的)。@ bekce 的回答很棒,最初也想走这条路,但要么就是在争论中表现得古怪。或者在子类中执行参数化操作,丢失确切测试通过/失败的信息,只有最后一个截图(截图名称从测试本身获得名称)。所以不管怎样都有点混乱。

在我的例子中,跑步者非常简单,所以我克隆了这个类的源代码,给它起了我自己的名字 参数化运行器,在我原来扩展 TestRunner的地方,我的类扩展了 参数化类,所以本质上我可以使用我自己的 Runner 而不是前两个。归结起来,我自己的运行器扩展到了参数化运行器的顶部,同时在顶部实现了屏幕截图功能,现在我的测试使用了这个“混合”运行器,所有的测试立即按预期工作(不需要改变测试内部的任何东西)。

下面是它看起来的样子(为了简洁起见,我从清单中删除了所有的注释) :

package mySwtTests;


import org.junit.runners.Parameterized;
import org.eclipse.swtbot.swt.finder.junit.ScreenshotCaptureListener;
import org.junit.runner.notification.RunListener;
import org.junit.runner.notification.RunNotifier;


public class ParametrizedScreenshotRunner extends TestRu Parameterized {


public ParametrizedScreenshotRunner(Class<?> klass) throws Throwable {
super(klass);
}


public void run(RunNotifier notifier) {
RunListener failureSpy = new ScreenshotCaptureListener();
notifier.removeListener(failureSpy); // remove existing listeners that could be added by suite or class runners
notifier.addListener(failureSpy);
try {
super.run(notifier);
} finally {
notifier.removeListener(failureSpy);
}
}
}

虽然 JUnit 4中没有解决方案,但是可以在 JUnit 5中注册多个扩展:

@ExtendWith(MockitoExtension.class)
@ExtendWith(AnotherExtension.class)
public class MyTest {
// some tests
}

请注意,JUnitParams框架内置于 JUnit5中。