I'm using Mockito for unit testingand I'm getting the following exception.
<%= form_for(@challenge, html: { data: { modal: true } }) do |f| %>
<%= hidden_field_tag :step, 2 %>
etc...
<% end %>
Here is the actual class
org.mockito.exceptions.base.MockitoException:
`'setResponseTimeStampUtc'` is a *void method* and it *cannot* be stubbed with a *return value*!
Voids are usually stubbed with Throwables:
doThrow(exception).when(mock).someVoidMethod();
***
If you're unsure why you're getting above error read on.
Due to the nature of the syntax above problem might occur because:
1. The method you are trying to stub is *overloaded*. Make sure you are calling the right overloaded version.
2. Somewhere in your test you are stubbing *final methods*. Sorry, Mockito does not verify/stub final methods.
3. A spy is stubbed using `when(spy.foo()).then()` syntax. It is safer to stub spies -
- with `doReturn|Throw()` family of methods. More in javadocs for Mockito.spy() method.
this is the Test class I have written.
@Repository
public class CardRepositoryImpl implements ICardRepository {
@Autowired
private OperationBean operation;
@Override
public OperationBean getCardOperation(final String cardHolderId, final String requestTimeStamp) {
operation.setRequestTimeStampUtc(requestTimeStamp);
operation.setResponseTimeStampUtc(DateUtil.getUTCDate());
return operation;
}
}
Is this an issue with the return statement since format() method is a final method.
@RunWith(MockitoJUnitRunner.class)
public class CardRepositoryImplUnitTestFixture_Mockito {
@InjectMocks
private CardRepositoryImpl cardRepositoryImpl;
private OperationBean operationBean;
@Before
public void beforeTest() {
MockitoAnnotations.initMocks(this);
}
@Test
public void canGetCardOperation(){
when(cardRepositoryImpl.getCardOperation("2", Mockito.anyString())).thenReturn(operationBean);
}
}
How can I resolve this?
答案 0 :(得分:4)
@InjectMocks
private CardRepositoryImpl cardRepositoryImpl;
when(cardRepositoryImpl.getCardOperation("2", Mockito.anyString()))
.thenReturn(operationBean);
cardRepositoryImpl
不是模拟,因此您无法将其存根。使用@InjectMocks
,您指示Mockito构造一个真正的CardRepositoryImpl,并将其私有字段和构造函数参数替换为测试用例中的字段。你可能想要使用间谍;更多关于这一点。
但首先,为什么会显示错误消息?因为它不是模拟,所以对cardRepositoryImpl.getCardOperation
的调用发生在实际的CardRepositoryImpl实例上。 Mockito看到与operationBean
的交互(这似乎是模拟),将when
和thenReturn
视为与最近的模拟通话相对应,并错误地告诉您&#39;使用返回值重写一个void方法(重要的是,错误的方法)。
在对CardRepositoryImpl的测试中,你不应该嘲笑CardRepositoryImpl,也不应该抄袭它来返回值:这不会测试任何东西,除了Mockito有效。你可能应该重新考虑存根需要什么才能让你的测试工作。
但是,当存根一个方法时,您可能希望在同一个类中存根另一个方法。这可以通过间谍来实现:
@Test
public void canGetCardOperation(){
CardRepositoryImpl spyImpl = spy(cardRepositoryImpl);
when(spyImpl.getCardOperation(Mockito.eq("2"), Mockito.anyString()))
.thenReturn(returnValue);
// ...
spyImpl.someOtherMethod(); // Any matching calls to getCardOperation from
// someOtherMethod will use the stub above.
}
附注:在存根时,您会相邻地使用anyString
和"2"
。当使用像anyString
这样的匹配器时,如果您将它们用于任何参数,则需要将它们用于所有参数。 See more here.