我写单元测试,并希望使用JUnitParamsRunner
和MockitoJUnitRunner
一个测试类。
不幸的是,以下操作无效:
@RunWith(MockitoJUnitRunner.class)
@RunWith(JUnitParamsRunner.class)
public class DatabaseModelTest {
// some tests
}
有没有一种方法可以在一个测试类中同时使用Mockito和JUnitParams?
我写单元测试,并希望使用JUnitParamsRunner
和MockitoJUnitRunner
一个测试类。
不幸的是,以下操作无效:
@RunWith(MockitoJUnitRunner.class)
@RunWith(JUnitParamsRunner.class)
public class DatabaseModelTest {
// some tests
}
有没有一种方法可以在一个测试类中同时使用Mockito和JUnitParams?
Answers:
您不能执行此操作,因为根据规范,您不能将相同的注释两次放在相同的注释元素上。
那么,解决方案是什么?解决的办法是只放一个@RunWith()
你无法忍受的赛跑者,然后用其他东西代替。对于您的情况,我想您将删除MockitoJUnitRunner
并以编程方式执行此操作。
实际上,它唯一要做的就是运行:
MockitoAnnotations.initMocks(test);
在测试用例的开始。因此,最简单的解决方案是将以下代码放入setUp()
方法中:
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
我不确定,但是您可能应该避免使用flag多次调用此方法:
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();
您可以与任何所需的运行程序一起运行此测试用例。
mockInitialized
是否错误。您想为每一次测试准备一个新鲜的模拟。
从JUnit 4.7和Mockito 1.10.17开始,此功能是内置的。有一个org.mockito.junit.MockitoRule
课。您可以简单地将其导入并添加行
@Rule public MockitoRule mockitoRule = MockitoJUnit.rule();
参加您的测试班。
@Rule public MockitoJUnitRule mockito = new MockitoJUnitRule(this);
MockitoAnnotations.initMocks(this)
创建模拟非常慢。最有效的方法是使用@Runwith(MockitoJunitRunner.class)
该解决方案适用于所有可能的跑步者,而不仅是这个模仿示例。例如; 对于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
取决于它(通过逻辑),它将在调用过程中在main 内部的@Test
方法中运行JUnitCore.runClasses(TestMockitoJUnitRunner.class)
。此方法可确保主运行程序在static class TestMockitoJUnitRunner
子运行程序运行之前正确启动,从而有效地实现@RunWith
具有相关测试类的多个嵌套注释。
也在https://bekce.github.io/junit-multiple-runwith-dependent-tests
JUnitCore.runClasses()
如果不检查结果就进行调用,则可能会掩盖内部测试中的错误。assert(JUnitCore.runClasses(TestMockitoJUnitRunner.class).wasSuccessful());
至少会向您报告错误
自从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/
就我而言,我试图在春豆中模拟一些方法,
MockitoAnnotations.initMocks(test);
不起作用。相反,您必须定义要在xml文件中使用模拟方法构造的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(...);
...
}
查看此链接https://bekce.github.io/junit-multiple-runwith-dependent-tests/ 使用此方法,我将@RunWith(Parameterized.class)-外流道-与@RunWith(MockitoJUnitRunner.class)-内部跑步者。我唯一需要添加的调整是使外部类/跑步者中的成员变量静态化,以使内部/嵌套跑步者/类可以访问它们。祝你好运,享受。
我想同时运行SWTBotJunit4ClassRunner和org.junit.runners.Parameterized,我有参数测试,我想在SWT测试失败时截屏(截屏功能由SWTBotJunit4ClassRunner提供)。@bekce的答案很好,首先想走这条路线,但是通过参数传递古怪。或在子类中进行参数化,并丢失信息,确切的测试通过/失败了,并且只有最后一个屏幕截图(因为屏幕截图名称是从测试本身获取的名称)。所以无论哪种方式都有点混乱。
就我而言,SWTBotJunit4ClassRunner很简单,因此我克隆了该类的源代码,给它起了自己的名字ParametrizedScreenshotRunner,而原来是在扩展TestRunner的地方,我的类是在扩展Parameterized类,因此从本质上讲,我可以使用自己的运行器而不是前两个。归结起来,我自己的运行程序扩展到了参数化运行程序的顶部,同时实现了它的屏幕快照功能,现在我的测试使用此“混合”运行程序,并且所有测试都可以按预期工作(无需在测试内部进行任何更改)。
这是它的样子(为简洁起见,我从清单中删除了所有评论):
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);
}
}
}
您也可以尝试以下操作:
@RunWith(JUnitParamsRunner.class)
public class AbstractTestClass {
// some tests
}
@RunWith(MockitoJUnitRunner.class)
public class DatabaseModelTest extends AbstractTestClass {
// some tests
}