Reputation: 705
I have a following @Component
with an injected object that makes a chain method call to get something, e.g.
@Component
public class MyInterceptor implements ClientHttpRequestInterceptor {
@Autowired
public MyProducer producer;
@Override
public ClientHttpResponse intercept(…) throws IOException {
String val = producer.getProducer().getSomeVal(/*parameters*/); // LINE (1)
}
}
And my test class is:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = { MyInterceptor.class, MyProducer.class } )
public class MyInterceptorTest {
private RestTemplate restTemplate = new RestTemplate();
private MockRestSErviceServer mockServer;
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Mock
public MyProducer producer;
@InjectMocks
private MyInterceptor interceptor;
@Before
public void init() {
//MockitoAnnotation.initMocks(this);
producer = Mockito.mock(MyProducer.class, Mockito.RETURNS_DEEP_STUBS);
// adding interceptor to RestTemplate
mockServer = MockRestServiceServer.createServer(restTemplate);
when(producer.getProducer().getSomeVal(null, null)).thenReturn("SomeValue");
}
@Test
public void myTestMethod() {
mockServer.expect(requestTo(/*some dummy URL*/)
.andExpect(method(HttpMethod.GET))
.andExcept(/*some header stuff omitted from MyInterceptor */)
.andRespond(withSuccess(/*…*/));
// This is going to trigger the Interceptor being invoked
restTemplate.getForEntity("some dummy URL", String.class); // LINE (2)
mockServer.verify();
}
}
When the test executes LINE (2), and it invokes the interceptor, in LINE (1) I get a null pointer exception.
I was under the assumption that by enabling deep stubbing on a mock, I would be able to make a chain call and get an expected value, e.g. producer.getProducer().getSomeVal()
, but it doesn't seem to be the case.
Do you know how I can get this working as expected?
P.S. I have tried different variation of adding MockitoAnnotation.initMocks()
and getting rid of @Rule
, or just @Autowired
MyInterceptor
in the test class which in this causes MyProducer
not to be mocked at all, but nothing seems to work.
Note, MyProducer
cannot be modified as it is from another project.
Upvotes: 1
Views: 3370
Reputation: 11822
You've mocked the MyProducer
class, but you haven't provided a when
for producer.getProducer()
.
So, when the code calls producer.getProducer()
it will return the default mock value, which is null.
You could try a couple of different approaches:
when(producer.getProducer()).thenReturn(producer);
I'm not sure if that will work - it might.
Otherwise, you may be able to write a local test class that implements/extends whatever getProducer() returns, which in turn returns the appropriate test value when the correct parameters are passed to getSomeVal()
.
Upvotes: 1