开始使用TDD和存储库模式,我想知道测试这个是否有意义......
使用存储库模式,我有这个界面:
public interface ICustomerRepository
{
IList<Customer> List();
Customer Get(int id);
}
我有50个不同的实体,所以50个不同的存储库接口/实现。
我的问题是,通过模拟界面测试每个存储库是否正确,如:
[TestMethod]
public void List_Should_Return_Two_Customers()
{
// Arrange
var customerr = new List<Customer>();
customer.Add(new Customer());
customer.Add(new Customer());
var repository = new Mock<ICustomerRepository>();
repository.Setup(r => r.List()).Returns(customer);
// Assert
Assert.AreEqual(2, repository.Object.List().Count);
}
[TestMethod]
public void Get_Should_Return_One_Customer()
{
// Arrange
var customer = new List<Customer>();
customerr.Add(new Customer() { Id = 1 });
customerr.Add(new Customer() { Id = 2 });
var repository = new Mock<ICustomerRepository>();
repository.Setup(r => r.Get(1)).Returns(customer.Where(w => w.Id == 1).First());
// Assert
Assert.IsTrue(repository.Object.Get(1).Id == 1);
}
测试这些接口的虚假实现是否有意义?对我来说没有。
答案 0 :(得分:3)
不,没有意义。显然你应该只测试实现,而不是接口。在界面中没有什么可以测试的。
在您的示例中测试的唯一内容是模拟框架,.NET列表和一些LINQ扩展方法。没有必要对它们进行测试,其他人已经开始对此进行测试。
也许目的是为接口存在并具有某些方法的事实提供单元测试?在这种情况下,测试仍然是不必要的。这是由依赖于接口声明的其他代码的测试隐式测试的。
当您需要虚假实现以测试其他代码时,您应该只创建一个ICustomerRepository
模拟。
答案 1 :(得分:0)
是的,测试每个存储库是“正确的”。存储库用于将数据库从代码中抽象出来,并且应该验证它们是否正常工作。您的数据访问层可以说是最重要的测试组件之一。
答案 2 :(得分:0)
其他人是对的。 你无法测试接口。 你实际上正在测试模拟,这没有意义。 通常我会针对数据库测试存储库,因此,对它们进行单元测试并不是那么多。 为了测试他们之上的任何东西我嘲笑他们。 请记住,50种类型的实体并不意味着50个存储库。
问候。
答案 3 :(得分:0)
我可以提出替代解决方案...... 像您的存储库一样简单(如果它们都是相同的方法,除了它们返回的内容)为什么不使用泛型创建基类。那么你只需要测试基类。
public interface IRepository<TEntity> where TEntity : class
{
IList<TEntity> List();
TEntity Get(int id);
}
public abstract class BaseRepository<TEntity> : IRepository<TEntity> where TEntity : class
{
IList<TEntity> List()
{
//DataContext.GetTable<TEntity>().ToList();
}
TEntity Get(int id)
{
//Might have to do some magic here... you can use reflection or create
//an abstract method that the derived class must override that returns
//a delegate id selector.
}
}