为什么在JUnitParams方法中设置字段变量后它们为null?

时间:2016-11-03 11:04:39

标签: java junit mockito junitparams

我正在使用JUnitParamsMockito编写测试类。我想将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};
    }
}

我用

  • JUnitParams版本1.0.5
  • JUnit版本4.12
  • Mockito版本1.10.19

为什么myList为null,我该如何解决?

2 个答案:

答案 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会支持这个(我还没试过)。单元测试通常应该彼此隔离,因此建议的操作是每次都创建一个新的模拟。