如何将@InjectMocks 与参数化测试一起使用
How do I use @InjectMocks with a Parameterized test
注意:我进行了搜索并阅读了各种博客,但找不到与我正在尝试做的相匹配的示例。
我有一个 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
can not access a member of class
com.company.converter.ConverterServiceTest with modifiers "private"
at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102) at
java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296)
at
java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288)
at java.lang.reflect.Field.set(Field.java:761) at
org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters.createTestUsingFieldInjection(BlockJUnit4ClassRunnerWithParameters.java:62)
at
org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters.createTest(BlockJUnit4ClassRunnerWithParameters.java:36)
at
org.junit.runners.BlockJUnit4ClassRunner.runReflectiveCall(BlockJUnit4ClassRunner.java:266)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at
org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner.run(ParentRunner.java:290) at
org.junit.runners.ParentRunner.schedule(ParentRunner.java:71) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at
org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:58) at
org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268) at
org.junit.runners.ParentRunner.run(ParentRunner.java:363) at
org.junit.runners.Suite.runChild(Suite.java:128) at
org.junit.runners.Suite.runChild(Suite.java:27) at
org.junit.runners.ParentRunner.run(ParentRunner.java:290) at
org.junit.runners.ParentRunner.schedule(ParentRunner.java:71) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at
org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:58) at
org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268) at
org.junit.runners.ParentRunner.run(ParentRunner.java:363) at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
它似乎不喜欢我的测试成员字段之一是私有的,但没有告诉我哪个字段有问题。我看过的所有单元测试例子,唯一的public一定是ExpectedException规则
对不起,我是个笨蛋。问题是 @Parameter(x) 内部成员需要 public,而不是私有的。
我花了很长时间寻找 Google。 :-)
注意:我进行了搜索并阅读了各种博客,但找不到与我正在尝试做的相匹配的示例。
我有一个 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 can not access a member of class com.company.converter.ConverterServiceTest with modifiers "private" at sun.reflect.Reflection.ensureMemberAccess(Reflection.java:102) at java.lang.reflect.AccessibleObject.slowCheckMemberAccess(AccessibleObject.java:296) at java.lang.reflect.AccessibleObject.checkAccess(AccessibleObject.java:288) at java.lang.reflect.Field.set(Field.java:761) at org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters.createTestUsingFieldInjection(BlockJUnit4ClassRunnerWithParameters.java:62) at org.junit.runners.parameterized.BlockJUnit4ClassRunnerWithParameters.createTest(BlockJUnit4ClassRunnerWithParameters.java:36) at org.junit.runners.BlockJUnit4ClassRunner.runReflectiveCall(BlockJUnit4ClassRunner.java:266) at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) at org.junit.runners.BlockJUnit4ClassRunner.methodBlock(BlockJUnit4ClassRunner.java:263) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) at org.junit.runners.ParentRunner.run(ParentRunner.java:290) at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:58) at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.junit.runners.Suite.runChild(Suite.java:128) at org.junit.runners.Suite.runChild(Suite.java:27) at org.junit.runners.ParentRunner.run(ParentRunner.java:290) at org.junit.runners.ParentRunner.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access[=11=]0(ParentRunner.java:58) at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:268) at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86) at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382) at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
它似乎不喜欢我的测试成员字段之一是私有的,但没有告诉我哪个字段有问题。我看过的所有单元测试例子,唯一的public一定是ExpectedException规则
对不起,我是个笨蛋。问题是 @Parameter(x) 内部成员需要 public,而不是私有的。
我花了很长时间寻找 Google。 :-)