java 使用 Mockitos 传递参数化输入

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12606148/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 09:31:47  来源:igfitidea点击:

passing Parameterized input using Mockitos

javaunit-testingmockito

提问by spal

I am using Mockito for unit testing. I am wondering if its possible to send Parametrized input parameters with as in Junit testing
e.g

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

回答by Jeff Bowman

In JUnit, Parameterized testsuse a special runnerthat ensure that the test is instantiated multiple times, so each test method is called multiple times. Mockito is a tool for writing specific unit tests, so there is no built-in ability to run the same test multiple times with different Mockito expectations.

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

If you want your test conditions to change, your best bet is to do one of the following:

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

  • Parameterize your test using JUnit, with a parameter for the mock inputs you want;
  • Run a loop of different parameters in your test, which unfortunately avoids the "test one thing per method" philosophy
  • Extract a method that actually performs the test, and create a new @Testmethod for each mock you want.
  • 使用 JUnit 参数化您的测试,并为您想要的模拟输入设置一个参数;
  • 在您的测试中运行不同参数的循环,不幸的是避免了“每个方法测试一件事”的理念
  • 提取实际执行测试的方法,并@Test为您想要的每个模拟创建一个新方法。

Note that there's no prohibition on using mock objects as @Parameterizedtest parameters. If you're looking to parameterize based on mocks, you can do that, possibly creating the mock and setting the expectations in a static method on the test.

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



Note about runners: This Parameterized test runnerconflicts with Mockito's MockitoJUnitRunner: Each test class can only have one runner. You'll want to switch to @Before and @After methodsor a Mockito JUnit4 rulefor your setup, if you use them both.

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

As an example, compressed from a different answerthat explains more about Parameterized runners versus JUnit rules and lifting from the JUnit4 Parameterized Testdoc page and MockitoRuledoc page:

例如,从一个不同的答案压缩而来,该答案解释了更多关于参数化运行程序与 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 */ }
}

回答by kavai77

If you are stuck with an older version of mockito where MockitoRuleisn't available, the other possibility is to initialize the mocks explicitely with MockitoAnnotations.initMocks:

如果您坚持使用旧版本的 mockitoMockitoRule不可用,另一种可能性是使用以下命令显式初始化模拟MockitoAnnotations.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 */ }
}

回答by JohnPlata

You can use the JUnitParamsRunner. Here's how I do it:

您可以使用 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},
        });
    }
}