我使用Mockito和MockMvc进行控制器单元测试。
在POST请求之后,POSTed对象被正确解析,但我的存储库模拟没有被触发。
这是模拟代码:
Date mydate = new Date();
Notification not = new Notification();
not.setId(-1L);
not.setUserid("BaBlubb");
not.setTimestamp(mydate);
not.setContent("MyContent");
Notification not2 = new Notification();
not2.setId(1L);
not2.setUserid("BaBlubb");
not2.setTimestamp(mydate);
not2.setContent("MyContent");
when(notificationRepository.save(not)).thenReturn(not2);
所以这真的应该模拟对象的保存(设置ID并从中生成路径)。
不幸的是,存储库总是返回null,因此我的代码稍后在尝试将新创建的Route返回null时失败。
模拟是正确注入的,并且可以用于例如字符串比较或者如果我只检查要调用的函数,我就是不能让它在对象上触发。
上出现同样的问题
verify(notificationRepository, times(1)).save(not);
它不会触发。
问题是: 1.)为什么模拟不会触发?我认为它不会检查对象中的值相等性,而是检查对象标识符,因为对象在序列化和反序列化之间是不相同的。
2.。)如何获得通用模拟?例如每当调用repository.save()时,无论参数如何,它总是应该执行特定的方式,例如而不是
when(notificationRepository.save(not)).thenReturn(not2);
我想要
when(notificationRepository.save()).thenReturn(not2);
P.S。如果由于某种原因你需要剩下的代码,这里是提交的部分,对象是通知的json表示(用jackson)
mockMvc.perform(post("/api/notification").content(object)
.contentType(MediaType.APPLICATION_JSON)
.accept(MediaType.APPLICATION_JSON));
这里是Controller头,Object完全反序列化,值是1:1相同
@RequestMapping(method=RequestMethod.POST)
public ResponseEntity<?> postNotification(@RequestBody Notification n) {
logger.debug("Saving userid "+n.getId());
感谢您的帮助。
答案 0 :(得分:0)
1。)为什么模拟不会触发?我想它不会检查对象中的值相等性,而是检查不同的对象标识符......
默认情况下,Mockito会委托您对象的char s[]
方法。如果你没有覆盖它,那么它默认检查引用。以下两行是等效的:
equals
如果具有相同字段的所有Notification对象相同,则覆盖when(notificationRepository.save(not)).thenReturn(not2);
when(notificationRepository.save(not)).thenReturn(eq(not2)); // uses eq explicitly
和equals
将使您获得所需的位置。但要注意,这可能会对Set和Map行为产生意想不到的副作用,特别是如果Notification对象在保存之前没有ID。
2.。)如何获得通用模拟?例如每当调用repository.save()时,无论参数如何,它总是应该执行特定的方式
使用Matchers,这非常简单:
hashCode
虽然Matchers非常强大,但要注意:他们have some tricky rules与他们的使用有关。
答案 1 :(得分:0)
对于(1),如Jeff所述,您可能需要使用eq()而不是直接引用col_1 + ' ' + col_2 = 'a b c'
对于(2)您可以使用not1
对于例如Mockito.any()
这将在模拟对象 notificationRepository 上创建存根,对于任何类型为when(notificationRepository.save(any(Notification.class))).thenReturn(not2);
的参数,它总是返回not2
。如果Notification
方法接受Object,那么您可以编写save()
,对when(notificationRepository.save(any(Object.class))).thenReturn(not2);
类型的任何参数返回not2