简体   繁体   中英

Mocking entity framework repository

I use MEF for DI and MOQ for mocking.

The same unit test with the Get() works perfectly fine but Get(2) absolutely not. MEF is correctly initialized and MOQ too. I receive null all the time. It's the exact same code, except I have an argument to Get() method but with an argument. I use GetEntity in the abstract class and not GetEntities() like for the working test.

FYI, no problem at all when I hit the database.

public class TestClass
{
    [Import]
    IDataRepositoryFactory _DataRepositoryFactory;

    public TestClass()
    {
        ObjectBase.Container.SatisfyImportsOnce(this);
    }

    public TestClass(IDataRepositoryFactory dataRepositoryFactory)
    {
        _DataRepositoryFactory = dataRepositoryFactory;
    }

    public IEnumerable<Customer> GetCustomers()
    {
        ICustomerRepository customerRepository = _DataRepositoryFactory.GetDataRepository<ICustomerRepository>();
        IEnumerable<Customer> customers = customerRepository.Get();
        return customers;
    }

    public Customer GetCustomers(int id)
    {
        ICustomerRepository customerRepository = _DataRepositoryFactory.GetDataRepository<ICustomerRepository>();
        Customer customer =  customerRepository.Get(id);
        return customer;
    }
}

[TestMethod]
public void GetById()
{
    List<Customer> customers = new List<Customer>()
    {
        new Customer() { CustomerId = 1, FirstName = "AAA" },
        new Customer() { CustomerId = 2, FirstName = "BBB" }
    };

    Mock<ICustomerRepository> mockCustomerRepository = new Mock<ICustomerRepository>();
    mockCustomerRepository.Setup(obj => obj.Get()).Returns(customers);

    Mock<IDataRepositoryFactory> mockDataRepository = new Mock<IDataRepositoryFactory>();
    mockDataRepository.Setup(obj => obj.GetDataRepository<ICustomerRepository>()).Returns(mockCustomerRepository.Object);

    DataClassFactory dataClassFactory = new DataClassFactory(mockDataRepository.Object);

    Customer ret = dataClassFactory.GetCustomers(2);

    Assert.IsNotNull(ret);
}

public interface IDataRepositoryFactory
{
    T GetDataRepository<T>() where T : IDataRepository;
}

public interface IDataRepository{}

public interface IDataRepository<T> : IDataRepository
    where T : class, IIdentifiableEntity, new()
{
    IEnumerable<T> Get();
    T Get(int id);
}

public abstract class DataRepositoryBase<T, U> : IDataRepository<T>
    where T : class, IIdentifiableEntity, new()
    where U : DbContext, new()
{
    protected abstract DbSet<T> DbSet(U entityContext);
    protected abstract Expression<Func<T, bool>> IdentifierPredicate(U entityContext, int id);

    T AddEntity(U entityContext, T entity)
    {
        return DbSet(entityContext).Add(entity);
    }

    IEnumerable<T> GetEntities(U entityContext)
    {
        return DbSet(entityContext).ToFullyLoaded();
    }

    T GetEntity(U entityContext, int id)
    {
        return DbSet(entityContext).Where(IdentifierPredicate(entityContext, id)).FirstOrDefault();
    }

    public IEnumerable<T> Get()
    {
        using (U entityContext = new U())
            return (GetEntities(entityContext)).ToArray().ToList();
    }

    public T Get(int id)
    {
        using (U entityContext = new U())
            return GetEntity(entityContext, id);
    }
}

Update

public class DataClassFactory
{
    [Import]
    IDataRepositoryFactory _DataRepositoryFactory;

    public DataClassFactory()
    {
        ObjectBase.Container.SatisfyImportsOnce(this);
    }

    public DataClassFactory(IDataRepositoryFactory dataRepositoryFactory)
    {
        _DataRepositoryFactory = dataRepositoryFactory;
    }

    public IEnumerable<Customer> GetCustomers()
    {
        ICustomerRepository customerRepository = _DataRepositoryFactory.GetDataRepository<ICustomerRepository>();
        IEnumerable<Customer> customers = customerRepository.Get();
        return customers;
    }

    public Customer GetCustomers(int id)
    {
        ICustomerRepository customerRepository = _DataRepositoryFactory.GetDataRepository<ICustomerRepository>();
        Customer customer =  customerRepository.Get(id);
        return customer;
    }
}

In GetById test method you use dataClassFactory.GetCustomers(2) which goes to the GetCustomers(int id) overload. That overload is calling customerRepository.Get(id) which goes to an overload that you didn't mock - this why it returns null.

This should solve it

Mock<ICustomerRepository> mockCustomerRepository = new Mock<ICustomerRepository>();
mockCustomerRepository.Setup(obj => obj.Get()).Returns(customers);
mockCustomerRepository.Setup(obj => obj.Get(It.IsAny<int>())).Returns((int i) => customers.FirstOrDefault(c => c.CustomerId == i)); // This is the new part

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM