I am trying to mock the following chain of method calls which are called from my ClassUnderTest.methodUnderTest:
((AService) System.getService(AService.NAME)).isA();
where the System.getService static method is declared to return a Service interface, but returns a concrete subclass based on the passed string parameter. isA() is a method on the AService subclass and does not exist on the Service interface, hence requiring the cast.
I am using JMockit (1.8) and have attempted to mock the call chain as follows
public class TestCascadingMock {
@Test
public void testMethodUnderTest(@Cascading System system) {
new Expectations(system) {{
((AService) System.getService(AService.NAME)).isA();
result = false;
}};
ClassUnderTest c = new ClassUnderTest();
boolean isA = c.methodUnderTest();
assertFalse(isA);
}
}
This is resulting in a ClassCastException
java.lang.ClassCastException: org.gwl.test.$Impl_Service cannot be cast to org.gwl.test.AService
at org.gwl.test.TestCascadingMock$1.<init>(TestCascadingMock.java:14)
at org.gwl.test.TestCascadingMock.testMethodUnderTest(TestCascadingMock.java:13)
I can understand what the excpetion is telling me - JMockit can only return a mocked implementation of Service, not AService - but how do I specify that I always wish this call to return false?
Thanks in advance.
Write the test as follows:
@Test
public void testMethodUnderTest(
@Mocked System system, @Mocked final AService aService)
{
new NonStrictExpectations() {{
System.getService(AService.NAME); result = aService;
aService.isA(); result = false;
}};
ClassUnderTest c = new ClassUnderTest();
boolean isA = c.methodUnderTest();
assertFalse(isA);
}
Note that the aService.isA()
expectation can be removed, if desired, since false
is the default value for methods returning boolean
.