使用 Mockitos 传递参数化输入

2022-09-01 10:40:03

我正在使用Mockito进行单元测试。我想知道是否有可能像在Junit测试
中那样发送参数化输入参数,例如

@InjectMocks
MockClass mockClass = new MockClass();

@Test
public void mockTestMethod()
    {
    mockClass.testMethod(stringInput); 
// here I want to pass a list of String inputs 
// this is possible in Junit through Parameterized.class.. 
// wondering if its can be done in Mockito
    } 

答案 1

在 JUnit 中,参数化测试使用一个特殊的运行程序来确保多次实例化测试,因此每个测试方法都调用多次。Mockito是一个用于编写特定单元测试的工具,因此没有内置功能来多次运行相同的测试,具有不同的Mockito期望。

如果您希望更改测试条件,最好的办法是执行以下操作之一:

  • 使用JUnit参数化测试,并为所需的模拟输入提供参数;
  • 在测试中运行不同参数的循环,不幸的是,这避免了“每个方法测试一件事”的理念
  • 提取实际执行测试的方法,并为所需的每个模拟创建一个新方法。@Test

请注意,不禁止将模拟对象用作测试参数。如果您希望基于模拟进行参数化,则可以执行此操作,可能创建模拟并在测试的静态方法中设置期望。@Parameterized


关于运行器的注意事项:此参数化测试运行程序与 Mockito 的 MockitoJUnitRunner 冲突:每个测试类只能有一个运行器。如果同时使用@Before和@After方法Mockito JUnit4 规则(如果同时使用它们),则需要切换到这些方法。

例如,从不同的答案压缩,该答案解释了有关参数化运行器与JUnit规则的更多信息,并从JUnit4参数化测试文档页面和MockitoRule文档页面提升:

@RunWith(Parameterized.class)
public class YourComponentTest {
    @Rule public MockitoRule rule = MockitoJUnit.rule();
    @Mock YourDep mockYourDep;

    @Parameters public static Collection<Object[]> data() { /* Return the values */ }

    public YourComponentTest(Parameter parameter) { /* Save the parameter to a field */ }

    @Test public void test() { /* Use the field value in assertions */ }
}

答案 2

如果您遇到旧版本的 mockito 不可用,另一种可能性是使用以下命令显式初始化 mocks:MockitoRuleMockitoAnnotations.initMocks

@RunWith(Parameterized.class)
public class YourComponentTest {        
    @Mock YourDep mockYourDep;

    @Parameter
    public Parameter parameter;

    @Parameters public static Collection<Object[]> data() { /* Return the values */ }

    @Before
    public void init() {
        MockitoAnnotations.initMocks(this);
    }

    @Test public void test() { /* Use the field value in assertions */ }
}

推荐