我有一個相當複雜的方法,我想測試行爲(使用Mockito和JUnit)。此方法將一個對象(我們稱其類型爲State
)作爲輸入,並應考慮幾個不同的狀態變量來決定其輸出。調用mockito中的模擬對象
作爲一個例子,考慮下面的說明書(s
是State
類的模擬):
- 如果
s.varOne
被設置,返回其值。 - 否則,如果設置了
s.varTwo
,則返回該值。 - 否則,如果
s.varThree
設置,調用s.update(s.varThree)
然後返回s.varOne
,現在將有一個值(即使它沒有在階段1) - 否則,拋出一個錯誤。
爲了測試案例3得當,我想建立s
對象,以便s.varOne
和s.varTwo
都沒有設置,開始用,但如果(且僅當!)的SUT調用s.update(s.varThree)
,再經過那s.varOne
返回的東西。
有沒有一種很好的方法來在Mockito中設置這種行爲?
我已經考慮爲s.varOne
設置一些返回值鏈,然後驗證調用的順序是否與輸出的順序相對應(以及當然,sut的返回值是否正確) ,但這感覺很髒;如果我然後改變方法來計算其返回值的方式,它調用s.varOne
不同的次數,但不會改變它的輸出,那麼即使功能相同,測試也會失敗。
我的理想解決方案是,我可以爲模擬對象添加一些「延遲」設置,當該對象調用s.update()
方法時運行該對象,但我無法找到實現該方法的方法。
關於您的測試的可疑之處在於您的第三個示例中您的模擬成爲測試中的系統。你可以讓模擬返回任何你想要的,但你想測試**模擬**返回一定條件下的東西。難道你不能重組你的代碼,以便你的SUT是一件事而不是1.x事情嗎? –
這聽起來像你在同一個測試用例中有多個斷言一樣。你能否把你的測試案例分解成更小的測試用例,每個測試用例只測試一個條件?你不應該在模擬中需要任何條件邏輯。如果您正在測試的代碼將模擬調用兩次,並且每次都要求不同的返回值,那麼只需將多個值傳遞給您的'thenReturn'調用(如我的示例http://stackoverflow.com/questions/8088179/using -mockito與 - 多呼叫到所述-相同方法-用最同參數/ 8395685#8395685)。 –
@DavidWallace:如問題所述,我不想創建一個返回值鏈,因爲這會使得測試依賴於實現而不僅僅依賴於合約(即「必須獲得varOne'兩次,然後調用'update()',然後重新獲得它,否則測試將失敗,即使合同 - 也許 - 仍然是全滿的)。 –