测试这个有意义吗? (存储库模式)

时间:2009-07-17 23:02:07

标签: c# unit-testing repository

开始使用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);
}

测试这些接口的虚假实现是否有意义?对我来说没有。

4 个答案:

答案 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.
    }
}