Issue
i am trying to make @SpyBean or @MockBean work in this test as they are working in all my other tests. the only difference here is this test uses an active profile because it mocks some AWS libs
I shouldnt have to instantiate the class it if I am using SpyBean, i've seen countless examples similar to mine below that seem to work fine.
The unit I'm testing:
@Component
public class SqsAdapter {
@Autowired
QueueMessagingTemplate queueMessagingTemplate;
@Autowired
MyProcessor processor;
@SqsListener("${queue.name}")
public void onEvent(String message) {
if (!StringUtils.isEmpty(message)) {
processor.process(message);
} else {
log.error("Empty or null message received from queue");
}
}
}
and a simple unit test to expect process(...) to be called:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = Application.class)
@ActiveProfiles("local")
public class SqsAdapterTest {
@Autowired
AmazonSQSAsync amazonSQS;
@SpyBean
MyProcessor processor;
@InjectMocks
SqsAdapter adapter;
@Test
public void testOnEvent() {
doNothing().when(processor).process(any()); // <---- process() is void
String event = "royale with cheese";
adapter.onEvent(event);
verify(processor, times(1)).process(event);
}
}
when i debug in the unit test, i get a java.lang.NullPointerException
on processor
as if it never gets initialized:
ive also tried switching it to @MockBean with the same results
furthermore, i also tried stripping the testing of the @SpringBootTest and the @ActiveProfiles ... and removed the AmazonSQSAsync dependency since im not mocking the Listener itself, and it still throws the same NPE
what am i missing here?
Solution
Think I've got it answered: seems to be because of mixing testing frameworks via having the @InjectMocks annotation mixed with @SpyBean ... since I was trying not to use Mockito mocks, and this is a Mockito annotation, i think it was screwing up the tests
the working unit test looks like:
@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("local")
public class SqsAdapterTest {
@Autowired
AmazonSQSAsync amazonSQS;
@SpyBean
SeamEventProcessor seamEventProcessor;
@Autowired
SqsAdapter adapter;
@Test
public void testOnEvent() {
doNothing().when(seamEventProcessor).process(any());
String event = "royale with cheese";
adapter.onEvent(event);
verify(seamEventProcessor, times(1)).process(event);
}
}
Answered By - heug
Answer Checked By - Mildred Charles (JavaFixing Admin)