模拟使用框架来生成一个“模拟对象”。例如,如果officeClass是您的数据存储库,则可以使用模拟框架(我使用MOQ)来生成一个存储库的模拟。这就是为什么使用接口作为依赖项进行测试是理想的,模拟框架可以轻松地为测试生成接口的模拟。
至于存根,据我了解,您需要手动替换依赖项并创建预置响应。例如,如果您有一个名为IOfficeClass的接口,并且您创建了一个从它继承的新类,您可以将该类注入到服务中以允许您使用它。
同样,像Web服务这样的事物应该包装在某个接口中(例如IRepository模式),这将使您能够轻松地测试逻辑而无需连接到Web服务。POCO类也是如此。
因此,例如,在您的情况下,您将拥有:
public interface IOfficeRepository
{
IQueryable<Office> GetAll();
}
为您服务
public class MyOfficeService
{
private readonly IOfficeRepository officeRepostiory;
public MyOfficeService(IOfficeRepository repository)
{
this.officeRepostiory = repository;
}
public Office GetOffice(int id)
{
return this.officeRepostiory.GetAll().SingleOrDefault(o => o.Id == id);
}
}
这样做,您可以更改底层数据源而无需修改主要应用程序或业务逻辑代码。
使用moq,您的单元测试将类似于以下内容:
[TestClass]
public class OfficeUnitTest
{
private MyOfficeService service;
[TestInitialize]
public void Setup()
{
var officeRepository = new Mock<IOfficeRepository>();
var office = new List<Office>();
office.Add(new Office{ Id = 1 });
officeRepository.Setup(m => m.GetAll()).Returns(office.AsQueryable());
this.service = new MyOfficeService(officeRepository.Object);
}
[TestMethod]
public void TestGetById()
{
Assert.IsNotNull(service.GetOffice(1));
Assert.IsNull(service.GetOffice(2));
}
}
以下可以了解有关mock和stub的更多信息:
http://martinfowler.com/articles/mocksArentStubs.html
http://msdn.microsoft.com/en-us/library/ff649690.aspx