Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/334.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java jUnit中的多个RunWith语句_Java_Unit Testing_Junit - Fatal编程技术网

Java jUnit中的多个RunWith语句

Java jUnit中的多个RunWith语句,java,unit-testing,junit,Java,Unit Testing,Junit,我编写单元测试,并希望对一个测试类使用junitpamsrunner和MockitoJUnitRunner 不幸的是,以下方法不起作用: @RunWith(MockitoJUnitRunner.class) @RunWith(JUnitParamsRunner.class) public class DatabaseModelTest { // some tests } 有没有办法在一个测试类中同时使用Mockito和junitpams?您不能这样做,因为根据规范,您不能在同一个带注释的元

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

不幸的是,以下方法不起作用:

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

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

您不能这样做,因为根据规范,您不能在同一个带注释的元素上放置同一个注释两次

那么,解决方案是什么?解决方案是只将一个
@RunWith()
放在你无法离开的runner上,然后用其他东西替换另一个。在您的情况下,我想您将删除
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();

你可以用任何你想要的跑步者来运行这个测试用例

从JUnit4.7和Mockito 1.10.17开始,这个功能是内置的;有一节课。您可以简单地导入它并添加行

@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
您也可以尝试以下方法:

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

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

在我的例子中,我试图在SpringBean和

MockitoAnnotations.initMocks(test);
不起作用。相反,您必须在xml文件中定义要使用mock方法构造的bean,如下所示

...
<bean id="classWantedToBeMocked" class="org.mockito.Mockito" factory-method="mock">
    <constructor-arg value="com.fullpath.ClassWantedToBeMocked" />
</bean>
...
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="file:springconfig.xml")
public class TestClass {
    ...
    @Autowired
    private ClassWantedToBeMocked classWantedToBeMocked;
    ...
    when(classWantedToBeMocked.methodWantedToBeMocked()).thenReturn(...);
    ...
}

此解决方案适用于所有可能的跑步者,而不仅仅是这个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
依赖于它(通过逻辑),它将在调用
JUnitCore.runClasses(TestMockitoJUnitRunner.class)
期间,以
@Test
方法在main内部运行。此方法确保在运行
静态类TestMockitoJUnitRunner
子运行程序之前正确启动主运行程序,从而有效地使用依赖测试类实现多个嵌套的
@RunWith
注释


此外,自PowerMock 1.6发布以来,您可以尽可能轻松地完成这项工作

@RunWith(PowerMockRunner.class)
@PowerMockRunnerDelegate(JUnitParamsRunner.class)
public class DatabaseModelTest {
  // some tests
}
此处已解释

查看此链接
使用这种方法,我将@RunWith(Parameterized.class)-外部运行程序-与@RunWith(MockitoJUnitRunner.class)-内部运行程序组合在一起。我必须添加的唯一调整是将外部类/运行程序中的成员变量设置为静态,以便内部/嵌套运行程序/类可以访问它们。祝你好运,好好享受。

我想运行SWTBotJunit4ClassRunnerorg.junit.runner.Parameterized同时,我有参数测试,我想在SWT测试失败时截屏(截屏功能由SWTBotJunit4ClassRunner提供)@Becke的回答很好,他首先想走这条路,但这要么是通过争论的诡异。或者在子类中进行参数化,丢失确切测试通过/失败的信息,并且只有最后一个屏幕截图(因为屏幕截图名称从测试本身获得名称)。所以无论哪种方式都有点混乱

在我的例子中,SWTBotJunit4ClassRunner非常简单,因此我克隆了该类的源代码,给它起了我自己的名字参数化ScreenshoRunner,并在原版扩展了TestRunner,我的课程正在扩展参数化的课程,因此本质上我可以使用自己的跑步者,而不是前两个。简而言之,我自己的runner在参数化runner的基础上进行了扩展,同时在其基础上实现了屏幕截图功能,现在我的测试使用了这个“混合”runner,所有测试都可以立即按预期工作(无需更改测试内部的任何内容)

这就是它的样子(为了简洁起见,我从列表中删除了所有注释):

包测试;
导入org.junit.runners.Parameterized;
导入org.eclipse.swtbot.swt.finder.junit.ScreenshotCaptureListener;
导入org.junit.runner.notification.RunListener;
导入org.junit.runner.notification.RunNotifier;
公共类参数化ScreenshoRunner扩展TestRu参数化{
公共参数Screenshotrunner(klass类)可丢弃{
超级(klass);;
}
公共无效运行(运行通知程序通知程序){
RunListener failureSpy=new ScreenshotCaptureListener();
RemovelListener(failureSpy);//删除可以由套件或类运行程序添加的现有侦听器
addListener(failureSpy);
试一试{
super.run(通知程序);
}最后{
通知程序。removeListener(failureSpy);
}
}
}

看一看:这里还有一个很好的例子:这不起作用,只处理子类注释。不起作用-只考虑MockitoJUnitRunner注释检查
mockInitialized
是错误的。你想为每一次tetst都制作一个新的模拟品。@BetaRide,这取决于你的需要。有时您希望每次都初始化mock,有时不希望。如果您希望为每个类文件设置一次,可以使用BeforeClass而不是Before,每个测试文件只调用一次。对于Mockito的旧版本(看起来是1.10.5),您必须使用:
@Rule public MockitoJUnitRule Mockito=new MockitoJUnitRule(此);
MockitoAnnotations.initMocks(this)
创建mock非常慢。最有效的方法是使用@Runwith(MockitoJunitRunner.class),但正如OP所提到的,您不能使用两个@Runwith语句,他需要使用另一个。通过调用
JUnitCore.runClasses()
而不检查结果,您就有可能掩盖内部测试中的错误<代码>断言(JUnitCore.runClasses(TestMockitoJUnitRunner.class)。
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);
        }
    }
}