0

I have an interface IRepository to abstract my repository:

Fake repository

public class Repository : IRepository
{
    IQueryable<User> _users;
    public IQueryable<User> Users
    {
        get
        {
            return _users ?? (_users = Enumerable.Empty<User>().AsQueryable());
        }
    }

    IQueryable<Couple> _couples;
    public IQueryable<Couple> Couples
    {
        get
        {
            return _couples ?? (_couples = Enumerable.Empty<Couple>().AsQueryable());
        }
    }

    IQueryable<Role> _roles;
    public IQueryable<Role> Roles
    {
        get
        {
            return _roles ?? (_roles = Enumerable.Empty<Role>().AsQueryable());
        }
    }

    public T Add<T>(T entity) where T : class
    {
        throw new System.NotImplementedException(); //Problem here!!
    }
}

I need to know, how to add an object in the right collection in my repository fake?

In my database repository, I not have this problem:

Database repository

public class Repository : DbContext, IRepository
{
    public DbSet<Role> Roles { get; set; }
    public DbSet<User> Users { get; set; }
    public DbSet<Couple> Couples { get; set; }

    public T Add<T>(T entity)
        where T : class
    {
        return Set<T>().Add(entity);
    }
... //More...
}

I know that the collections are not the same type, concealed this implementation to shorten the code.

All I want to know is how to maintain the same behavior from my database repository in my fake repository?

ridermansb
  • 10,779
  • 24
  • 115
  • 226
  • Shouldn't there be distinct repositories per type? – Austin Salonen Oct 08 '11 at 21:56
  • I've heard of this approach, but do not understand why should it? – ridermansb Oct 08 '11 at 22:04
  • 1
    Faking repository [doesn't make sense](http://stackoverflow.com/questions/6766478/unit-testing-dbcontext). Fakes are for tests and testing code with faked `IQueryable` = testing completely different code. What is a point of testing different code? – Ladislav Mrnka Oct 09 '11 at 09:19

3 Answers3

1

I think it would just be a matter of checking the type of entity:

public T Add<T>(T entity) where T : class 
{ 
    if (entity.GetType() == typeof(User))
    {
        // add user
    }
    else if (entity.GetType() == typeof(Couple))
    {
        // add couple
    }
    else if (entity.GetType() == typeof(Role))
    {
        // add role
    }
} 

Edit

I don't think you'll be able to add entities to _users, _roles, and _couples if they are created using Enumerable.Empty<T>(). You might consider

List<User> _users = new List<User>();

public IQueryable<User> Users
{
    get { return _users.AsQueryable(); }
}
Jeff Ogata
  • 56,645
  • 19
  • 114
  • 127
0

I would change the IRepository interface to be generic itself:

interface IRepository<T>
{
    IQueryable<T> Get();
    T Add(T item);
}

If you follow this route, your unit tests and mocking become very simple as you test the UserRepository, CoupleRepository, and RoleRepository separately.

Austin Salonen
  • 49,173
  • 15
  • 109
  • 139
  • understood, and how would my controller? There are actions that accesses two different repositories, I would have to instantiate the two in the constructor? – ridermansb Oct 08 '11 at 22:27
0

I personally think that the point of repository is to describe the domain root for specific entity and to be an endpoint between buisness logic and data persistance. And you should have one repository per domain root.

But anyway, take a look at this article, http://huyrua.wordpress.com/2010/07/13/entity-framework-4-poco-repository-and-specification-pattern/, I've learned alot from it.

And to answer your question, you can do following:

    public virtual void Add(TEntity entity)
    {
        if (entity == null)
        {
            throw new ArgumentNullException("entity");
        }
        // add caching here
        var set = Context.CreateObjectSet<TEntity>();
        set.AddObject(entity);           
    }

Where Context is your Entity Framework ObjectContext class.

v00d00
  • 3,215
  • 3
  • 32
  • 43