首先,我要说的是,尽管是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