首先,我要說的是,儘管是TDD的一名相當新的從業者,但我幾乎可以從中受益。我覺得我已經有足夠的進步來考慮使用嘲諷,並且在瞭解嘲笑與OOP適合的地方時碰到了一面真正的磚牆。關於嘲諷的另一個問題
我讀過儘可能多的相關文章/文章,我可以找到(Fowler,Miller),我仍然不完全清楚如何或何時模擬。
讓我舉一個具體的例子。我的應用程序有一個服務層類(有些人稱之爲應用層?),其中方法大致映射到特定用例。這些類可以與持久層,域層甚至其他服務類協作。我是一個善良的小男孩DI和已正確分解出來我的依賴,使他們能夠底塗用於測試目的等
樣本服務類可能是這樣的:
public class AddDocumentEventService : IAddDocumentEventService
{
public IDocumentDao DocumentDao
{
get { return _documentDao; }
set { _documentDao = value; }
}
public IPatientSnapshotService PatientSnapshotService
{
get { return _patientSnapshotService; }
set { _patientSnapshotService = value; }
}
public TransactionResponse AddEvent(EventSection eventSection)
{
TransactionResponse response = new TransactionResponse();
response.Successful = false;
if (eventSection.IsValid(response.ValidationErrors))
{
DocumentDao.SaveNewEvent(eventSection, docDataID);
int patientAccountId = DocumentDao.GetPatientAccountIdForDocument(docDataID);
int patientSnapshotId =PatientSnapshotService.SaveEventSnapshot(patientAccountId, eventSection.EventId);
if (patientSnapshotId == 0)
{
throw new Exception("Unable to save Patient Snapshot!");
}
response.Successful = true;
}
return response;
}
}
我使用NMock完成了對其方法(DocumentDao,PatientSnapshotService)進行隔離測試的過程。這裏的測試看起來像
[Test]
public void AddEvent()
{
Mockery mocks = new Mockery();
IAddDocumentEventService service = new AddDocumentEventService();
IDocumentDao mockDocumentDao = mocks.NewMock<IDocumentDao>();
IPatientSnapshotService mockPatientSnapshot = mocks.NewMock<IPatientSnapshotService>();
EventSection eventSection = new EventSection();
//set up our mock expectations
Expect.Once.On(mockDocumentDao).Method("GetPatientAccountIdForDocument").WithAnyArguments();
Expect.Once.On(mockPatientSnapshot).Method("SaveEventSnapshot").WithAnyArguments();
Expect.Once.On(mockDocumentDao).Method("SaveNewEvent").WithAnyArguments();
//pass in our mocks as dependencies to the class under test
((AddDocumentEventService)service).DocumentDao = mockDocumentDao;
((AddDocumentEventService)service).PatientSnapshotService = mockPatientSnapshot;
//call the method under test
service.AddEvent(eventSection);
//verify that all expectations have been met
mocks.VerifyAllExpectationsHaveBeenMet();
}
我對這個小涉足嘲諷的想法是什麼如下:
- 這個測試的出現打破許多基本OO戒律,而不是其中最重要的就是封裝:我測試深入瞭解被測試類的具體實現細節(即方法調用)。每當課程內部發生變化時,我都會發現很多無用的時間用於更新測試。
- 也許是因爲我的服務類目前相當簡單,但我不太明白這些測試增加了什麼價值。是否我保證協作對象正在按照特定用例的要求被調用?代碼重複似乎很荒謬,因爲這樣一個小小的好處。
我錯過了什麼?
「我缺少什麼?」 - 測試重構以消除冗餘代碼?即將常用步驟移到您的測試設置中。 – tvanfosson 2009-08-31 18:11:18