【发布时间】:2019-08-15 18:23:20
【问题描述】:
我在尝试对函数调用进行单元测试时遇到问题。对 void 方法调用 messageProducer.sendMessage() 的调用失败,即使它已被存根。
请在下面找到我的代码的简化快照。我正在使用 doAnswer() 存根来模拟 void 方法(基于 StackOverflow 上的早期答案)。
我什至尝试了doThrow() 和doNothing() 存根的其他选项,但在调用存根方法时它们也因相同的 NPE 而失败:(。
如果有人可以提出解决方案/解决方法,我们将不胜感激。非常感谢。
测试类
// Test class
@RunWith(MockitoJUnitRunner.class)
public class RetriggerRequestTest {
@Mock
private MessageProducer messageProducer;
@InjectMocks
private MigrationRequestServiceImpl migrationRequestService;
@Before
public void init() {
MockitoAnnotations.initMocks(this);
}
@Test
public void sendRetriggerRequest() throws Exception {
// Below two stubbings also not Work, NPE encountered!
//doNothing().when(messageProducer).sendMessage(any(), anyLong());
//doThrow(new Exception()).doNothing().when(messageProducer).sendMessage(any(), anyLong());
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
Object[] args = invocation.getArguments();
System.out.println("called with arguments: " + Arrays.toString(args));
return null;
}
}).when(messageProducer).sendMessage(any(EMSEvent.class), anyLong());
try {
// Gets Null pointer exception
migrationRequestService.retriggerRequest(emsRetriggerRequest);
}
catch (Exception ex) {
fail(ex.getMessage());
}
}
正在测试的实现类,来自此类的存根方法调用抛出 NPE,如代码 cmets 中所示
@Service
@Transactional
public class MigrationRequestServiceImpl implements MigrationRequestService {
@Autowired
MessageProducer messageProducer;
@Override
public void retriggerRequest(EMSRetriggerRequestData emsRetriggerRequestData) throws EMSException {
// Does a bunch of things
submitTaskScheduledEventsToQueue(taskList);
}
private void submitTaskScheduledEventsToQueue(List<Task> taskList) {
System.out.println("Debugging 1...");
taskList.stream().forEach(task -> {
System.out.println("Debugging 2...");
Map<String, Object> detailsMap = new HashMap<String, Object>();
EMSEvent event = new EMSEvent(EMSEventType.TASK_SCHEDULED);
event.setDetails(detailsMap);
LOGGER.info(ContextRetriever.getServiceContext(), ContextRetriever.getRequestContext(), "*** Re-submitting Task: *** " + task.getId());
// ****Gives a null pointer exception here****
messageProducer.sendMessage(event, eventsConfigProperties.getScheduledEventDelay());
});
System.out.println("Debugging 3...");
}
}
注入测试类的自动装配类,其方法是抛出NPE
@Service
public class MessageProducer {
private static final Logger logger = LoggerFactory.getLogger(MessageProducer.class);
private final RabbitTemplate rabbitTemplate;
@Autowired
public MessageProducer(RabbitTemplate rabbitTemplate) {
this.rabbitTemplate = rabbitTemplate;
}
public void sendMessage(EMSEvent emsEvent, Long delay) {
// code to send message to RabbitMQ here
}
}
【问题讨论】:
-
eventsConfigProperties来自哪里?看起来它们应该为空。 -
请添加完整的堆栈跟踪。它不太清楚
NPE来自哪里以及哪个对象为空。 -
感谢@daniu 指出这一点。正如我在下面的回答中给出的那样,我忽略了模拟这个自动装配的组件。
标签: java unit-testing mocking mockito