Asp.net mvc 在具有通用参数的存储库上进行单元测试

Asp.net mvc 在具有通用参数的存储库上进行单元测试,asp.net-mvc,unit-testing,repository,Asp.net Mvc,Unit Testing,Repository,假设我有一个通用的存储库类,大致如下所示: public class Repository<T> : IRepository<T> where T : class { IObjectSet<T> source; public Repository(IUnitOfWork transactionHandler) { source = transactionHandler.CreateObjectSet<T>(

假设我有一个通用的存储库类,大致如下所示:

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
}
公共类存储库:IRepository,其中T:class
{
IObjectSet源;
公共存储库(IUnitOfWork transactionHandler)
{
source=transactionHandler.CreateObjectSet();
}
公共IQueryable GetAll()
{
返回source.AsQueryable();
}
公共无效添加(T实体)
{
source.AddObject(实体);
}
//诸如此类的其他方法
}
我很难思考如何(甚至是否?)进行单元测试。 VisualStudio生成了一组我可以理解的测试,用于上面的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>));
}
public void GetAllTest()
{
GetAllTestHelper();//希望通过
尝试
{
GetAllTestHelper();//预期会引发异常
}
//捕获异常-检查它是否为预期类型等。
}
public void GetAllTestHelper(),其中T:class
{
IUnitOfWork transactionHandler=IUnitOfWorkFactory.GetUnitOfWork();
存储库目标=新存储库(transactionHandler);
IQueryable实际值=target.GetAll();
Assert.IsInstanceOfType(实际,typeof(IQueryable));
}
想法是-我可以证明调用此方法会返回类型为T的IQueryable。我还可以证明它会为无法生成IOObject集的类型(也是必需/需要的)引发InvalidOperationException

对于Add方法,我将进行循环

对于“为什么”-为什么要进行测试-我想我想证明我可以向存储库中添加一种类型的T,然后证明它已添加到DB中

对于“如何”-如上所述使用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
}
public void AddTest()
{    
AddTestHelper();
}
public void AddTestHelper(),其中T:class
{
IUnitOfWork transactionHandler=UnitTestHelper.GetUnitOfWork();
存储库目标=新存储库(transactionHandler);
T实体=默认值(T);
target.Add(entity);//引发异常-值不能为null
}
所以我的问题是 a) 您将如何对该存储库进行单元测试? 或者可能 b) 你会测试这个存储库吗

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

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

例如,下面是使用Rhino Mock对该存储库的
Add
方法进行的典型单元测试的样子:

[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));
}
[TestMethod]
public void Add_应在基础源()上使用
{
//安排
var uofStub=MockRepository.GenerateStub();
var objectSet=MockRepository.GenerateStub();
Stub(x=>x.CreateObjectSet()).Return(objectSet);
var sut=新存储库(uofStub);
var entity=“foo bar”;
//表演
补充(实体);
//断言
AssertWasCalled(x=>x.AddObject(实体));
}
就VisualStudio生成的自动测试组合而言,这可能是VS中最无用的功能之一

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

是的,绝对是