具有通用参数的存储库上的单元测试

时间:2011-06-17 21:52:56

标签: asp.net-mvc unit-testing repository

假设我有一个Generic Repository类,如下所示:

public class Repository<T> : IRepository<T> where T : class
{
    IObjectSet<T> source;
    public Repository(IUnitOfWork transactionHandler) 
    {
        source = transactionHandler.CreateObjectSet<T>();
    }

    public IQueryable<T> GetAll()
    {
        return source.AsQueryable<T>();
    }

    public void Add(T entity)
    {
        source.AddObject(entity);
    }
    //blah blah other methods
}

我无法理解如何(或者甚至?)我会对此进行单元测试。 Visual Studio生成一组测试,我可以理解上面的GetAll实现

public void GetAllTest()
{
    GetAllTestHelper<SomeExpectedType>();//expect this to pass
    try 
    {
        GetAllTestHelper<SomeUnexpectedType>();//expect this to throw exception
    }
    //catch exception - check it is expected type etc. 
}

public void GetAllTestHelper<T>() where T : class
{
     IUnitOfWork transactionHandler = IUnitOfWorkFactory.GetUnitOfWork();
     Repository<T> target = new Repository<T>(transactionHandler);

     IQueryable<T> actual = target.GetAll();

     Assert.IsInstanceOfType(actual, typeof(IQueryable<T>));
}

这个想法是 - 我可以证明调用此方法返回类型为T的IQueryable。我还可以证明它为无法生成IObjectSet的类型抛出InvalidOperationException(也需要/期望)。

对于Add方法,我将围成一圈。

对于'为什么' - 为什么要进行测试 - 我想我想证明我可以在存储库中添加一种类型的T,然后证明它已被添加到数据库中。

对于'how' - 使用上面的VS默认值,我得到的内容是

public void AddTest()
{    
    AddTestHelper<SomeExpectedType>();
}

public void AddTestHelper<T>() where T : class
{
    IUnitOfWork transactionHandler = UnitTestHelper.GetUnitOfWork();
    Repository<T> target = new Repository<T>(transactionHandler);

    T entity = default(T);

    target.Add(entity);//throws exception - value cannot be null
}

所以我的问题是 a)你将如何对这个存储库进行单元测试? 或者可能 b) 你测试这个存储库吗?

1 个答案:

答案 0 :(得分:2)

  

a)您将如何对此存储库进行单元测试?

Rhino MocksMoq之类的模拟框架可以简化单元测试此类的任务。它将用于模拟传递给存储库构造函数的IUnitOfWork接口。

例如,这里是这个存储库的Add方法的典型单元测试如何使用Rhino Mocks:

[TestMethod]
public void Add_Should_Use_AddObject_On_Underlying_Source()
{
    // arrange
    var uofStub = MockRepository.GenerateStub<IUnitOfWork>();
    var objectSet = MockRepository.GenerateStub<IObjectSet<string>>();
    uofStub.Stub(x => x.CreateObjectSet<string>()).Return(objectSet);
    var sut = new Repository<string>(uofStub);
    var entity = "foo bar";

    // act
    sut.Add(entity);

    // assert
    objectSet.AssertWasCalled(x => x.AddObject(entity));
}

就Visual Studio生成的测试的自动组合而言,恕我直言,这可能是VS中最无用的功能之一。

  

b)你会测试这个存储库吗?

是的,绝对。