2015-06-12 83 views
0

我有一個使用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,所以當我嘗試從null返回一個新創建的Route時,我的代碼失敗了。

嘲笑被正確地注入並且爲例如字符串比較,或者如果我只檢查被調用的函數,我就無法讓它在對象上觸發。發生在

 verify(notificationRepository, times(1)).save(not); 

它不會觸發

同樣的問題。

問題將是: 1.)爲什麼模擬不觸發?我想它不會檢查對象中的值是否相等,而是檢查對象標識符,因爲對象是序列化的和序列化的。

2.)我怎樣才能得到一個通用的模擬?例如無論何時調用repository.save(),無論參數如何,它都應該執行特定的方式,例如,而不是

when(notificationRepository.save(not)).thenReturn(not2); 

我想有

when(notificationRepository.save()).thenReturn(not2); 

附:如果出於某種原因,你需要的代碼的其餘部分,這裏是所提交的一部分,目的是通知(傑克遜)

mockMvc.perform(post("/api/notification").content(object) 
       .contentType(MediaType.APPLICATION_JSON) 
       .accept(MediaType.APPLICATION_JSON)); 

這裏的JSON表示是控制器頭,目的是反序列化完美的,值是1:1相同

@RequestMapping(method=RequestMethod.POST) 
    public ResponseEntity<?> postNotification(@RequestBody Notification n) { 
     logger.debug("Saving userid "+n.getId()); 

感謝您的幫助。

+0

的任何參數看看匹配器:http://site.mockito.org/mockito/docs/current/org/mockito/Matchers .html他們可以幫助你在這種調用中匹配某些參數。讓我知道它是否幫助你,如果不是我們如何解決問題。 –

回答

0

1.)爲什麼模擬不觸發?我想這不會檢查對象中的值相等,但對於對象標識符,這是不一樣的......

默認情況下,代表的Mockito到對象的equals方法。如果你沒有覆蓋它,那麼它會默認檢查引用。下面兩行是等價的:

when(notificationRepository.save(not)).thenReturn(not2); 
when(notificationRepository.save(not)).thenReturn(eq(not2)); // uses eq explicitly 

如果所有通告對象具有相同的字段是相同的,則覆蓋equalshashCode會得到你在哪裏,你需要去。但請注意,這可能會對Set和Map行爲產生意想不到的副作用,特別是如果您的Notification對象在保存之前沒有ID。

2.)我怎樣才能得到一個通用的模擬?例如每當repository.save()被調用,不管參數,它始終應該執行特定的方式

有了匹配器,這是非常簡單的:

when(notificationRepository.save(not)).thenReturn(any(Notification.class)); 

雖然匹配器非常強大,要注意:他們have some tricky rules與他們的使用相關聯。

0

對於(1),如由Jeff所提到的,可能需要使用當量(),而不是直接引用not1
對於(2)可以使用Mockito.any()
對於例如when(notificationRepository.save(any(Notification.class))).thenReturn(not2);
這將在模擬對象上創建存根notificationRepository對於任何類型爲Notification的參數,將始終返回not2。如果save()方法接受那麼對象,你可以寫when(notificationRepository.save(any(Object.class))).thenReturn(not2);這將返回not2類型Object