我使用存储库模式并有一个由相关单元测试实例化的虚拟存储库,它提供一组已知的数据,其中包含各个字段范围内和范围外的示例。
这意味着我可以通过在运行时从测试单元提供实例化存储库进行测试或提供生产存储库(通过依赖注入 (Castle))来测试我的代码。
我不知道有什么好的网络参考资料,但我从 Steven Sanderson 的 Apress 出版的 Professional ASP.NET MVC 1.0 书籍中学到了很多。 MVC 方法自然地提供了关注点分离,这是允许您的测试以更少的依赖项运行所必需的。
基本元素是您的存储库实现了一个用于数据访问的接口,然后由您在测试项目中构建的假存储库实现相同的接口。
在我当前的项目中,我有一个界面:
namespace myProject.Abstract
{
public interface ISeriesRepository
{
IQueryable<Series> Series { get; }
}
}
这既是作为我的实时数据存储库(使用 Linq to SQL)实现的,也是一个假存储库,因此:
namespace myProject.Tests.Respository
{
class FakeRepository : ISeriesRepository
{
private static IQueryable<Series> fakeSeries = new List<Series> {
new Series { id = 1, name = "Series1", openingDate = new DateTime(2001,1,1) },
new Series { id = 2, name = "Series2", openingDate = new DateTime(2002,1,30),
...
new Series { id = 10, name = "Series10", openingDate = new DateTime(2001,5,5)
}.AsQueryable();
public IQueryable<Series> Series
{
get { return fakeSeries; }
}
}
}
然后实例化使用数据的类,将存储库引用传递给构造函数:
namespace myProject
{
public class SeriesProcessor
{
private ISeriesRepository seriesRepository;
public void SeriesProcessor(ISeriesRepository seriesRepository)
{
this.seriesRepository = seriesRepository;
}
public IQueryable<Series> GetCurrentSeries()
{
return from s in seriesRepository.Series
where s.openingDate.Date <= DateTime.Now.Date
select s;
}
}
}
然后在我的测试中我可以这样处理它:
namespace myProject.Tests
{
[TestClass]
public class SeriesTests
{
[TestMethod]
public void Meaningful_Test_Name()
{
// Arrange
SeriesProcessor processor = new SeriesProcessor(new FakeRepository());
// Act
IQueryable<Series> currentSeries = processor.GetCurrentSeries();
// Assert
Assert.AreEqual(currentSeries.Count(), 10);
}
}
}
然后查看 CastleWindsor 以了解您的实时项目的控制反转方法,以允许您的生产代码通过依赖注入自动实例化您的实时存储库。这应该会让你更接近你需要去的地方。