模拟IDbSet时的TypeLoadException

时间:2013-01-19 19:02:15

标签: c# entity-framework mocking tdd repository

  

可能重复:
  How to mock IDbSet with Rhino Mocks

我正在尝试为我的存储库编写单元测试,但遇到了一个我无法理解的异常。

我将删除底部的实现作为参考,这一切都非常基础。

单元测试:

    [Test]
    public void AddTenantToRepository()
    {
        var dbSet = MockRepository.GenerateMock<IDbSet<Tenant>>();
        var dbContext = MockRepository.GenerateMock<IDbContext>();

        Expect.Call(dbContext.Set<Tenant>()).Return(dbSet);
        Expect.Call(dbSet.Add(new Tenant())).IgnoreArguments();

        var tenantRepository = new TenantRepository(dbContext);
        var tenant = new Tenant {Name = "tenant"};

        tenantRepository.Add(tenant);

        var tenantInRepository = tenantRepository.GetTenants().Single(t => t.Name.Equals("tenant"));
        Assert.IsNotNull(tenantInRepository);
    }

测试在我的测试的第一行引发异常:

MockRepository.GenerateMock<IDbSet<Tenant>>();

例外是:

  

System.TypeLoadException:类型'IDbSet 1Proxy29de06bbce3545de9c4e580c0b2791ed' from assembly 'DynamicProxyGenAssembly2, Version=0.0.0.0, Culture=neutral, PublicKeyToken=a621a9e7e5c32e69' tried to implicitly implement an interface method with weaker type parameter constraints. at System.Reflection.Emit.TypeBuilder.TermCreateClass(RuntimeModule module, Int32 tk, ObjectHandleOnStack type) at System.Reflection.Emit.TypeBuilder.CreateTypeNoLock() at System.Reflection.Emit.TypeBuilder.CreateType() at Castle.DynamicProxy.Generators.Emitters.AbstractTypeEmitter.BuildType() at Castle.DynamicProxy.Generators.InterfaceProxyWithTargetGenerator.GenerateCode(Type proxyTargetType, Type[] interfaces, ProxyGenerationOptions options) at Castle.DynamicProxy.DefaultProxyBuilder.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyTypeWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options) at Castle.DynamicProxy.ProxyGenerator.CreateInterfaceProxyWithoutTarget(Type interfaceToProxy, Type[] additionalInterfacesToProxy, ProxyGenerationOptions options, IInterceptor[] interceptors) at Rhino.Mocks.MockRepository.MockInterface(CreateMockState mockStateFactory, Type type, Type[] extras) at Rhino.Mocks.MockRepository.CreateMockObject(Type type, CreateMockState factory, Type[] extras, Object[] argumentsForConstructor) at Rhino.Mocks.MockRepository.DynamicMock(Object[] argumentsForConstructor) at Rhino.Mocks.MockRepository.<>c__DisplayClass7上的方法'Create'1.b__6(MockRepository r)          在Rhino.Mocks.MockRepository.CreateMockInReplay(Func`2 createMock)          在Rhino.Mocks.MockRepository.GenerateMock(Object [] argumentsForConstructor)          在TenantRepositoryTests.cs中的Tests.DAL.Tenants.TenantRepositoryTests.AddTenantToRepository():第31行

为什么我得到一个异常,即接口的约束条件较弱?所有接口(包括.net)都是公共的。我尽我所能,但到目前为止没有任何帮助。

提前多多感谢。

这里是其他类/接口(SuT)

租户资料库:

public class TenantRepository : Repository<Tenant>
{
    public TenantRepository(IDbContext context) : base(context)
    {
    }

    public IQueryable<Tenant> GetTenants()
    {
        return GetAll();
    }

    new public void Add(Tenant tenant)
    {
        base.Add(tenant);
    }

    public bool Exists(string tenantName)
    {
        var foundTenant = GetTenants().SingleOrDefault(tenant => tenant.Name.Equals(tenantName));
        return foundTenant != null;
    }
}

通用存储库:

public class Repository<TEntity> : IRepository<TEntity> where TEntity : class, IEntity
{
    private IDbContext _context;

    public Repository(IDbContext context)
    {
        _context = context;
    }

    private IDbSet<TEntity> DbSet
    {
        get { return _context.Set<TEntity>(); }
    }

    public IQueryable<TEntity> GetAll()
    {
        return DbSet.AsQueryable();
    }

    public void Delete(TEntity entity)
    {
        DbSet.Remove(entity);
    }

    public void Add(TEntity entity)
    {
        DbSet.Add(entity);
    }

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (disposing)
        {
            if (_context != null)
            {
                _context.Dispose();
                _context = null;
            }
        }
    }
} 

租户类:

public class Tenant : IEntity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Guid { get; set; }
    public List<User> Users { get; set; } 

    public Tenant()
    {
        Users = new List<User>();
    }
}

IEntity界面:

public interface IEntity
{
    int Id { get; set; }
}

IDbContext接口

public interface IDbContext
{
    IDbSet<TEntity> Set<TEntity>() where TEntity : class;
    int SaveChanges();
    void Dispose();
} 

0 个答案:

没有答案