我试图模拟一个dao方法,它创建一个记录,然后在输入上设置id。
下面是一些伪代码
抽样检验
RecordDto input = new RecordDto();
input.setId(null);
input.setName("test");
when(dao.createRecord(any(RecordDto.class)).thenReturn(1);
createSomething(input);
模拟方法
public int createRecord(RecordDto input) {
int updatedRowCount = 0;
int primaryKey = db call to create record
rows += primary != null ? 1 : 0;
input.setId(primaryKey) <-
return updateRowCount;
}
被测类
public void createSomething(RecordDto input)
int rowsUpdated = dao.createRecord(input);
if (input.getId() != null) {
do something <- this code can not be reached from my test
because my mock only sets the return value. It needs to also
modify the input.id.
}
一旦在我的真实的类中调用了这个方法,输入就有了一个id。我的mock只返回1作为行计数,但id仍然为空。
2条答案
按热度按时间mwngjboj1#
我的猜测是,你只是在dao方法内部模拟值返回,但不是副作用。您正在将
RecordDto
作为参数传递,执行一些操作并调用修改接收到的参数状态的方法。解决方案是使用doAnswer
,它不仅允许您返回值,还可以添加一些额外的逻辑。所以,你的测试应该看起来像这样:这将是快速的解决方案。
我认为这并不是最好的方法。在方法内部执行副作用可能会在将来导致bug,并且很难知道问题的根本原因,甚至很难进行调试。返回一个
RecordDto
或另一个自定义对象,让你知道新的id和受影响的行或类似的东西,这将使你的测试更容易设置,也使Assert。hmae6n7t2#
如果您需要一些额外的mocking行为,而不是简单地返回一个值,您可以在
when
mocking存根中使用thenAnswer
而不是thenReturn
。我希望这个(过于)简化的例子能有所帮助: