使用Mockitos传递参数化输入



我正在使用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
} 

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

如果你想改变你的测试条件,你最好的办法是做以下之一:

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

请注意,没有禁止使用模拟对象作为@Parameterized测试参数。如果你想基于mock进行参数化,你可以这样做,可能会创建mock并在测试的静态方法中设置期望值。


关于runner的注意:此参数化测试runner与Mockito的MockitoJUnitRunner冲突:每个测试类只能有一个runner。如果同时使用@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 */ }
}

如果您一直使用旧版本的mockito,其中MockitoRule不可用,另一种可能性是使用MockitoAnnotations.initMocks:显式初始化mock

@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 */ }
}

您可以使用JUnitParamsRunner。我是这样做的:

import junitparams.JUnitParamsRunner;
import junitparams.Parameters;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import java.util.Arrays;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.mockito.Mockito.when;
import static org.mockito.MockitoAnnotations.initMocks;
@RunWith(value = JUnitParamsRunner.class)
public class ParameterizedMockitoTest {
@InjectMocks
private SomeService someService;
@Mock
private SomeOtherService someOtherService;
@Before
public void setup() {
initMocks(this);
}
@Test
@Parameters(method = "getParameters")
public void testWithParameters(Boolean parameter, Boolean expected) throws Exception {
when(someOtherService.getSomething()).thenReturn(new Something());
Boolean testObject = someService.getTestObject(parameter);
assertThat(testObject, is(expected));
}
@Test
public void testSomeBasicStuffWithoutParameters() {
int i = 0;
assertThat(i, is(0));
}
public Iterable getParameters() {
return Arrays.asList(new Object[][]{
{Boolean.TRUE, Boolean.TRUE},
{Boolean.FALSE, Boolean.FALSE},
});
}
}

为我解决问题的是:

  1. @ExtendWith(MockitoExtension.class)的类级注释
  2. @Mock标注每个模拟对象
  3. 测试类上的@InjectMocks。或者一个用@BeforeEach注释的设置方法,初始化要测试的类
  4. 如果您需要@test注释,请确保导入org.junit.jupiter.api.Testorg.junit.test不起作用

我使用的是mockito版本4。

相关内容

  • 没有找到相关文章

最新更新