Note: I have done a search and read various blogs, but cannot find an example that matches what I am trying to do.
I have a ConverterService which uses a CodeService that is injected into it. I am attempting to write a JUnit test in which I mock the CodeService and inject that mock into the ConverterService under test. The test is Parameterized.
Consider the following code:
@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));
}
}
I am using the Parameterized.class runner, I am using MockitoAnnotations.initMocks(this), my @Before is initialising the mock CodeService, but I am not getting injection into ConverterService. In fact I am getting some strange reflection errors:
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$1.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$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.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$3.run(ParentRunner.java:290) at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at org.junit.runners.ParentRunner$2.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)
It seems to not like one of my test member fields being private, but is not telling me which one it has a problem with. All examples of unit tests I have seen, the only public must be the ExpectedException rule.
2条答案
按热度按时间mwecs4sa1#
对不起,我是一个笨蛋。问题是@参数(x)内部成员需要是公共的,而不是私有的。
我花了很长时间在谷歌上搜索这个。:-)
0md85ypi2#
在我的情况下,这个代码保证了我的生命安全