1

我正在使用JUnitParamsand编写一个测试类Mockito。我想使用Mockito mockas 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 为空,我该如何解决?

4

2 回答 2

3

MockitoJUnitParamsTest 类的实例运行parametersForTest() 方法是不一样的运行test()。这是因为 Junit 将为每个测试方法创建不同的实例。在您的情况下,将 myList 设为静态

private static List myList;

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

于 2016-11-03T11:30:44.023 回答
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 是否会支持这一点(我没有尝试过)。单元测试通常应该相互隔离,因此建议的操作是每次都创建一个新的模拟。

于 2016-11-03T11:50:48.000 回答