我正在使用JUnitParams
和Mockito
编写测试类。我想将Mockito mock
用作parameter
。在我的测试中,我有大约十个模拟,我想只传递一个模拟来定义它的特殊行为。
我在一个简单的例子中重现了这个问题。
我的问题:我在方法myList
中初始化变量parametersForTest
,但当我调试test
方法时,myList
为空,但是param
是我想要的嘲笑。
@RunWith(JUnitParamsRunner.class)
public class MockitoJUnitParamsTest {
private List myList;
@Test
@Parameters
public void test(List param) {
assertThat(param).isEqualTo(this.myList);
}
public Object[] parametersForTest() {
myList = Mockito.mock(List.class);
return new Object[]{myList};
}
}
我用
为什么myList为null,我该如何解决?
答案 0 :(得分:3)
运行parametersForTest()方法的MockitoJUnitParamsTest类的实例与运行test()的运行方式不同。这是因为Junit将为每个测试方法创建一个不同的实例。 在您的情况下,使myList静态
private static List myList;
可以部分解决问题,但如果测试并行运行可能会失败。
答案 1 :(得分:2)
JUnit框架和运行器通常为每个方法调用创建测试类的单独实例。它看起来像是JUnitParams所做的 - 你可以看到使用以下测试:
@RunWith(JUnitParamsRunner.class)
public class JUnitParamsTest {
@Test
@Parameters
public void test(JUnitParamsTest param) {
Assert.assertNotNull(param);
Assert.assertNotSame(this, param);
}
Object[] parametersForTest() {
return new Object[]{this};
}
}
因此,上述示例的问题在于myList
设置的parametersForTest
字段是与test(List)
被调用的对象不同的对象的成员。
嗯,我想关键问题是,你想在这里实现什么? JUnitParams的整个点是将参数注入到测试方法中,因此您不必使用字段。在我看来,修改parametersForTest()
方法中的字段值超出了预期用途,我无法理解你为什么要这样做。
一个快速而又脏的修复方法是使myList
静态,只要您的测试类不被多个线程同时访问(一些单元测试环境确实运行多线程),这应该可以工作这里存在风险)。
更好的解决方案是重新设计测试,以便您不会从参数生成方法中修改字段。你给出的例子似乎并没有试图测试JUnitParams本身以外的任何东西,所以我无法帮助你确定一个好的设计是什么,因为我儿子不知道你想要实现的目标。你是说你想要几个测试方法分享一个Mockito模拟?如果是这样,为什么?我不确定Mockito会支持这个(我还没试过)。单元测试通常应该彼此隔离,因此建议的操作是每次都创建一个新的模拟。