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

Why are field variables null after setting them in JUnitParams method?

我正在使用 JUnitParamsMockito 编写测试 class。我想将 Mockito mock 用作 parameter。在我的测试中,我有大约十个模拟,我只想传递一个模拟来为其定义特殊行为。

我在一个简单的例子中重现了这个问题。

我的问题:我在方法parametersForTest中初始化变量myList,但是当我调试到test方法时myList为null,但是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 为空,我该如何解决?

MockitoJUnitParamsTest 实例 class 运行ning parametersForTest() 方法与 运行ning test() 不同。这是因为 Junit 会为每个测试方法创建不同的实例。 在你的情况下,使 myList 静态

private static List myList;

可以部分解决问题,但并行测试运行可能会失败。

JUnit 框架和 运行 开发人员经常为每个方法调用创建单独的测试实例 class。看起来这就是 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};
    }

}

所以上面示例的问题在于 parametersForTest 设置的 myList 字段是与调用 test(List) 的对象不同的对象的成员。

如何修复

嗯,我想关键问题是,你想在这里实现什么? JUnitParams 的整个 是参数被注入到测试方法中,因此您不必使用字段。在我看来,在 parametersForTest() 方法中修改字段值超出了预期用途,我真的不明白你为什么要这样做。

一个快速而肮脏的修复方法是使 myList 静态化,只要您的测试 class 没有被多个线程同时访问(一些单元测试环境会 运行多线程所以这里有风险)。

更好的解决方案是重新设计您的测试,这样您就不会从参数生成方法内部修改字段。您给出的示例似乎没有尝试测试 JUnitParams 本身以外的任何内容,因此我无法帮助您确定什么是好的设计,因为我不知道您要实现什么。你是说你想要几个测试方法来 共享 一个 Mockito 模拟?如果是这样,为什么?我不确定 Mockito 会支持这个(我没试过)。单元测试通常应该相互隔离,因此建议的操作是每次都创建一个新的模拟。