【发布时间】:2016-11-11 16:55:19
【问题描述】:
我正在使用 Mockito/PowerMockito 在 java 中编写单元测试,但在我正在进行的测试中,我无法摆脱这个 UnfinishedStubbingException。
我要测试的方法是私有的,所以我使用 WhiteBoxImpl 来调用该方法。在我调用的方法中,可能会调用被测类中的另一个私有方法(称为 pm2)。我想验证从未调用过 pm2,因此我为被测类创建了一个间谍,并验证从未调用过 pm2。
到目前为止,这个测试总是抛出 UnfinishedStubbingException,但我无法弄清楚我的测试 Powermockito 不喜欢的部分。我有另一个(工作)测试,它的操作非常相似,除了我不需要验证像 pm2 这样的方法的行为。所以在这个工作案例中,我不需要为被测类创建间谍。我相信我的问题与间谍有关,但我不知道如何在没有它的情况下测试我要测试的内容。
这是我现在拥有的:
@Mock(name = "BO")
BO BOMock;
@Mock(name = "DAO")
DAOI DAOMock;
@InjectMocks
ServiceImpl service;
@Test
public void unitTest(){
MessageObject msg = new MessageObject();
Record recordMock = mock(Record.class);
MetaData metaDataMock = mock(MetaData.class);
doNothing().when(DAOMock).doAction(any(Param1.class), anyInt());
when(DAOMock.doOtherAction(any(Param1.class), eq(msg.getId()))).thenReturn(recordMock);
when(BOMock.getMetaData(anyInt(), anyInt()).thenReturn(metaDataMock);
ServiceImpl spy = PowerMockito.spy(this.service);
PowerMockito.doReturn(new Long(10)).when(spy, "checkDelay", recordMock, msg, metaDataMock);
Whitebox.invokeMethod(spy, "process", msg);
verify(recordMock, never()).getStatus();
}
这是我正在测试的 ServiceImpl 类中的方法:
private BO BO = new BO();
private DAOI DAO = new DAO();
private void process(Message msg) {
try {
DAO.doAction(new Param1.class, msg.getId());
} catch(Exception e) {
logger.error("some message");
return;
}
Record record = null;
try {
int intParam1 = msg.getId();
int intParam2 = msg.getDifferentId();
MetaData metaData = BO.getMetaData(intParam1, intParam2);
record = DAO.loadRecord(new Param1(), msg.getId());
// checkDelay is a private method in ServiceImpl.java
long delayForMinutes = checkDelay(record, msg, metaData);
if(delayForMinutes > 0) {
// Control should reach here
logger.debug("some message");
return;
}
// Control should not reach here
if(Record != null && Record.getStatus() != CREATED) {
logger.debug("some message");
return;
}
// Perform various actions
} catch(Exception e) {
// Perform other various actions
}
}
当我运行这个测试时,我得到了一个 UnfinishedStubbingException。堆栈跟踪顶部的行是:
DAO.doAction(new Param1.class, msg.getId());
错误信息提供以下提示:
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
但我似乎无法弄清楚它们中的任何一个如何适用于我的情况。有谁知道幕后发生了什么导致这个错误?
谢谢
【问题讨论】:
-
UnitTests 不应测试实现细节。因此,您的测试不需要知道您的类中有任何非公共方法。您应该将 DAO 的实例注入您的服务类并模拟它以进行测试(不使用 PowerMock ...)
标签: java unit-testing mocking mockito stubbing