【发布时间】:2021-10-01 10:40:54
【问题描述】:
我无法使用 mockito 模拟私有方法,但方法访问说明符可以被打包或保护,所以我这样做了。但即使在那之后,当实际方法包含其他几个受保护的方法调用时,我也无法实现单元测试抛出异常。
来源:
public class ConsumeService {
private DataProcessService dataProcessService;
@JmsListener
public void getMessage(final Message message) throws InterruptedException {
if (message instanceof TextMessage) {
TextMessage textMessage = getTextMessage(message);
try {
Map<String, String> attributes = prepareInfo(textMessage);
dataProcessService.processRequestData(
message.getText(), attributes);
} catch (JMSException e) {
log.error("JMSException in message");
} catch (ResourceAccessException e) {
log.error("IOException in message");
}
} else {
log.error("message convertion failed!");
}
}
}
TextMessage getTextMessage(final Message message) {
return (TextMessage) message;
}
Map<String, String> prepareInfo(TextMessage message) throws JMSException {
..
..
return result;
}
测试方法:
@ExtendWith(MockitoExtension.class)
public class ConsumeServiceTest {
@InjectMocks ConsumeService consumeService;
@Mock DataProcessService dataProcessService;
@Test
public void receiveMessageException() throws ResourceAccessException, JMSException{
TextMessage message = mock(TextMessage.class);
TextMessage textMessage = mock(TextMessage.class);
Map<String, String> mockMap = mock(HashMap.class);
when(consumeService.getTextMessage(message)).thenReturn(textMessage); //67 line
when(consumeService.prepareInfo(textMessage)).thenReturn(mockMap);
Mockito.lenient().
when(
dataProcessService.processRequestData(
textMessage.getText(), mockMap))
.thenThrow(ResourceAccessException.class);
assertThrows(
ResourceAccessException.class,
() -> this.consumeService.getMessage(message));
}
}
错误:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
Mocking methods declared on non-public parent classes is not supported.
2. inside when() you don't call method on mock but on some other object.
at com.sample.rest.listner.service.ConsumeServiceTest.receiveMessageException(ConsumeServiceTest.java:67)
我完全不知道如何解决这个问题。我了解错误在于存根,但我不了解如何解决此问题。 其次,一个对类特别有用的 util 方法可以在同一个文件中声明为私有的。我不明白为什么 mockito 不鼓励以这种方式模拟或测试私有/静态方法?有可能吗?我正在使用带有 junit5 的 mockito
更新
修改了测试方法
更新的测试方法:
@Test
public void receiveMessageException() throws ResourceAccessException, JMSException{
TextMessage message = mock(TextMessage.class);
Mockito.lenient().
when(
dataProcessService.processRequestData(
Mockito.anyString(), Mockito.any(Map.class)))
.thenThrow(ResourceAccessException.class);
assertThrows(
ResourceAccessException.class,
() -> this.consumeService.getMessage(message));
}
现在错误是
org.opentest4j.AssertionFailedError: Expected org.springframework.web.client.ResourceAccessException to be thrown, but nothing was thrown.
我的假设是它在这一行中失败 Map
【问题讨论】:
-
你的测试方法sn-p好像无效,没有声明方法。你能修一下吗?另外,您能否指定哪个行号/
when语句抛出MissingMethodInvocationException? -
在
sourcesn-p中没有prepareMetaData方法,在test methodsn-p中出现。 -
对不起,我现在添加了测试方法块,并重命名了方法名称@StefanoCordio
标签: unit-testing junit mockito junit5 spring-jms