如何将@InjectMocks与参数化测试

时间:2018-02-07 13:40:03

标签: java dependency-injection mockito parameterized

注意:我已经完成了搜索和阅读各种博客,但找不到符合我要做的事情的示例。

我有一个ConverterService,它使用注入的CodeService。我正在尝试编写一个JUnit测试,我在其中模拟CodeService并将该模拟注入到测试中的ConverterService中。测试是参数化的。

请考虑以下代码:

@RunWith(Parameterized.class)
public class ConverterServiceTest {

    @Parameters(name="{index}; Test case {0}")
    public static Collection<Object[]> initTestCases() {
        final Object[][] testCases = {
                { "One",   "First",   TypeEnum.ONE   },
                { "Two",   "Second",  TypeEnum.TWO   },
                { "Three", "Third",   TypeEnum.THREE },
                { "Four",  "Fourth",  TypeEnum.FOUR  },
                { "Five",  "Fifth",   TypeEnum.FIVE  },
                { "Six",   "Unknown", TypeEnum.BLANK }
        };
        return Arrays.asList(testCases);
    }

    @Parameter(0) private String   testName;
    @Parameter(1) private String   testCode;
    @Parameter(2) private TypeEnum expectedCode;

    @Rule public ExpectedException expected = ExpectedException.none();
    @Mock private CodeService codeService;
    @InjectMocks private ConverterService converter;

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

        when(codeService.isOne(anyString())).thenReturn(false);
        when(codeService.isOne("First")).thenReturn(true);

        when(codeService.isTwo(anyString())).thenReturn(false);
        when(codeService.isTwo("Second")).thenReturn(true);

        when(codeService.isThree(anyString())).thenReturn(false);
        when(codeService.isThree("Third")).thenReturn(true);

        when(codeService.isFour(anyString())).thenReturn(false);
        when(codeService.isFour("Fourth")).thenReturn(true);

        when(codeService.isFive(anyString())).thenReturn(false);
        when(codeService.isFive("Fifth")).thenReturn(true);
    }

    @Test public void testCodeConverter() {
        assertThat(converter.convert(testCode), equalTo(expectedCode));
    }
}

我正在使用Parameterized.class运行器,我正在使用MockitoAnnotations.initMocks(this),我的@Before正在初始化模拟CodeService,但我没有注入ConverterService。事实上,我得到了一些奇怪的反射错误:

  

java.lang.IllegalAccessException:Class   org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters   无法访问班级成员   com.company.converter.ConverterServiceTest with modifiers&#34; private&#34;     在sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102)at   java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)     在   java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)     在java.lang.reflect.Field.set(Field.java:761)at   org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters.createTestUsingFieldInjection(BlockJUnit4ClassRunnerWithParameters.java:62)     在   org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters.createTest(BlockJUnit4ClassRunnerWithParameters.java:36)     在   org.junit.runners.BlockJUnit4ClassRunner $ 1.runReflectiveCall(BlockJUnit4ClassRunner.java:266)     在   org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)     在   org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)     在   org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)     在   org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)     在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290)at at   org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71)at at   org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)at at   org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58)at at   org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268)at at   org.junit.runners.ParentRunner.run(ParentRunner.java:363)at at   org.junit.runners.Suite.runChild(Suite.java:128)at   org.junit.runners.Suite.runChild(Suite.java:27)at   org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290)at   org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71)at at   org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)at at   org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58)at at   org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268)at at   org.junit.runners.ParentRunner.run(ParentRunner.java:363)at at   org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)     在   org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)     在   org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)     在   org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)     在   org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)     在   org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

似乎不喜欢我的一个测试成员字段是私有的,但是没有告诉我哪个字段有问题。我看到的所有单元测试的例子,唯一的公共必须是ExpectedException规则。

1 个答案:

答案 0 :(得分:0)

抱歉,我是个骗子。问题是@Parameter(x)内部成员需要公开,而不是私有。

我花了一个时间在Google上搜索。 : - )