2013-05-16 63 views
0

我用我的最新項目使用TDD方法。它對我來說是新的:)TDD最佳實踐?

我有一個服務將保存CSV記錄到數據庫。它將檢查存在的值並在必要時添加 - 因此可以使用多個DAO。

下面是一個測試運行正常 - 但有人可以告訴我,如果有更好的方式來寫這個?它感覺不對。

感謝

@Test 
public void loadTest() { 
    //mock....all methods called in my save method 
    Dao1 dao1 = mock(Dao1.class); 
    when(dao1.findByDescription(anyString())).thenReturn(mock(Model1.class)); 
    Dao2 dao2 = mock(Dao2.class); 
    when(dao2.findByDescription(anyString())).thenReturn(mock(Model2.class)); 
    Dao3 dao3 = mock(Dao3.class); 
    when(dao3.findByDescription(anyString())).thenReturn(mock(Model3.class)); 
    Dao4 dao4 = mock(Dao4.class); 

    RowFromCsv row = mock(RowFromCsv.class); 
    when(row.getAttribute1()).thenReturn(new DateTime()); //otherwise test fails - nullpointerexception 
    when(row.getAttribute2()).thenReturn(new DateTime()); 
    Csv csv = mock(Csv.class); 
    when(csv.next()).thenReturn(row).thenReturn(null); 

    //this is what im testing... 
    Service load = new Service(); 
    load.setDao1(dao1); 
    load.setDao2(dao2); 
    load.setDao3(dao3); 
    load.setDao4(dao4); 
    load.save(csv); 

    //save called ok... 
    verify(dao4).createOrUpdate(any(Model4.class)); 
} 
+0

你太嘲笑了。在這個測試中'Model','RowFromCsv'和'Csv'類幾乎肯定不會被模擬。 –

+0

請詳細說明 - 它確實覺得我太嘲笑了。但是,如果我不嘲笑這些,那麼我該如何正確測試我的保存方法? – mryan

+0

我的意思是測試應該使用這些類unmocked。 'Model1','RowFromCsv'等看起來好像可以簡單地在測試代碼中實例化,並具有測試所需的值。 –

回答

1

測試看起來OK。你設置你的燈具,執行該方法,然後驗證它做了你的預期。

如果您創建了一個用作模擬工廠的實用程序類,則可以使其更具可讀性。假設方法findByDescription(string)類或接口BaseDao定義,你可以這樣做以下:

public class MockFactory { 
    public static <D extends BaseDao,M> D mockDao(Class<D> daoClass, Class<M> modelClass) { 
     D dao = mock(daoClass); 
     M model = mock(modelClass); 
     when(dao.findByDescription(anyString())).thenReturn(model)); 
     return dao; 
    } 

    public static Csv csvWithOneRecord() { 
     RowFromCsv row = mock(RowFromCsv.class); 
     when(row.getAttribute1()).thenReturn(new DateTime()); 
     when(row.getAttribute2()).thenReturn(new DateTime()); 
     Csv csv = mock(Csv.class); 
     when(csv.next()).thenReturn(row).thenReturn(null); 
    } 
} 

這種方法使你的測試更具可讀性和你的嘲弄可重用。 只要確保工廠方法有名稱描述他們返回什麼樣的模擬。如果你需要大量的吸入工廠方法,那麼你應該創建多個工具類,每個工具類專用於一種類型的模擬。即DaoMockFactoryCsvMockFactory

一兩件事:它是按照一定的命名規則是一個好主意:

  • 有一個測試類每一個主類即class TestServiceclass Service
  • 以正在測試的方法命名的單元測試方法,即方法testSave()測試方法save()