2012-04-09 57 views
3

我需要測試一個服務類,但是當我嘗試模擬dao類時,它不會被觸發,因此無法使用ThenReturn()。爲什麼Mockito的when()被觸發?

我覺得現在的問題是我用一個接口,用於吾道和@Autowired服務類(Spring MVC的3.1):

接口:

public interface TestDao { 
    int createObject(Test test) throws NamingException; 
} 

實施:

@Repository 
public class TestDaoImpl implements TestDao { 

    @Override 
    public int createObject(Test test) { 
     KeyHolder keyHolder = new GeneratedKeyHolder(); 
     jdbcTemplate.update(new InsertNewTest(test), keyHolder); 
     return ((java.math.BigDecimal)keyHolder.getKey()).intValue(); 
    } 
} 

服務:

public class RegTest { 
    @Autowired 
    TestDao testDao; 

    public int regTest(int .....) { 
     . 
     . 
     int cabotageId = testDao.createObject(test); 
    } 
} 

在測試我有:

@RunWith(MockitoJUnitRunner.class) 
public class TestRegService { 
    @InjectMocks 
    private RegTest regTest = new RegTest(); 

    @Mock 
    TestDao testDao; 

    @Test() 
    public void test() { 
     . 
     when(testDao.createObject(null)).thenReturn(100); 
     . 
    } 

testDao.createObject(空)返回0(由於被mock'ed),而不是100我正在努力實現。

有人可以幫忙嗎?

問題解決了!

這是通過測試對象createObject(),不匹配。使用

testDao.createObject(any(Test.class)) 

做了詭計!

+1

我試圖重現你的問題,但是當我做到這一點時,我得到了合適的返回值。你如何檢查createObject的結果?你可以在'when'調用之後,簡單地'System.out.println(testDao.createObject(null))'看看它說了什麼。如果它說100,那麼你知道問題是與測試,而不是模擬。如果它表示0,那麼它是Mockito的一種錯誤。 – jhericks 2012-04-09 16:59:59

+0

嗯...它說0 :-(我會嘗試其他建議之前,我報告它作爲一個bug ... – mamruoc 2012-04-09 19:08:55

回答

3

如果您的測試實際上是將值傳遞給createObject,那麼when(testDao.createObject(null) ......永遠不會匹配。您可以匹配TesttestDao.createObject(any(Test.class))之間的任何實例,而不是匹配null。

此外,當您後來又嘗試過提供new Test()作爲參數來搭配,它會從字面上嘗試匹配的Test,準確的實例,但想必你真正的代碼是新-ING一個不同的一個。所以使用Matchers.any(Test.class)作爲參數來匹配是一條路。

+0

是的,問題解決了!謝謝! – mamruoc 2012-04-09 20:23:18

0

我認爲你說得對,autowire沒有被調用。您可以使用setTestDao()調用自己注入dao。 Mockito還支持spy,它允許您跟蹤對象代碼並替換功能。

+0

我很新的春天MVC和Mockito,所以有關注射或使用@Spy的一些幫助將非常感謝! – mamruoc 2012-04-09 19:21:24

+0

Autowire告訴Spring尋找TestDao的配置並將RegTest設置爲該對象。但單元測試不使用Sprint,因此testDao從未設置爲對象。您可以自己設置測試以擁有TestDao。您可能想在[StackOverflow](http://stackoverflow.com/q/5643702/369446)或[Wikipedia](http://en.wikipedia.org/wiki/Inversion_of_control)上查找_reverse dependance injection_ ) – 2012-04-09 19:36:03

1

我不知道這是否是示例中的錯字,但您有RegTest.regTest()調用createTest()而不是createObject()。否則,我不認爲@Autowired與它有任何關係,因爲你的測試本身沒有在Spring管理的容器中運行。如果它不是拼寫錯誤,並且createTest實際上是與createObject實際不同的方法,那麼Mockito中模擬對象的默認行爲是爲數字返回類型返回適當類型的零。

+0

這是一個錯字,現在在問題中修復了,謝謝... – mamruoc 2012-04-09 19:11:51

2

Mockito注入機制不知道Spring @Autowired或CDI @Inject註釋。它只是試圖找到給定類型和模擬名稱的最佳候選人,並且它也可以查找私人領域。查看@InjectMocks的javadoc:http://docs.mockito.googlecode.com/hg/1.9.0/org/mockito/InjectMocks.html

您使用的語義是正確的,但如果您遇到問題,我寧願查找不正確的交互或不正確的參數。

您確定變量regTest.regTest(int...)確實是null傳遞給testDao.createObject(test)

+0

不,它是一個Test()對象,我試圖用'new Test()'而不是'null'提供它,但是結果相同 – mamruoc 2012-04-09 19:09:46

+3

好,如果你的測試實際上是通過一個值,噸hen'when(testDao.createObject(null)...'永遠不會匹配。你可以將任何Test的實例與'testDao.createObject(any(Test.class))...' – 2012-04-09 19:50:44

+0

Kevin相匹配,而any()匹配器則可以做到這一點。請創建一個答案,我會接受你的,如果你想:-) – mamruoc 2012-04-09 19:58:50

相關問題