Chris
Chris

Reputation: 8412

Use moq to mock a type with generic parameter

I have the following interfaces. I'm not sure how I can use Moq to mock up an IRepository due to the fact that T is generic. I'm sure there's a way, but I haven't found anything through searching through here or google. Does anybody know how I can achieve this?

I'm fairly new to Moq, but can see the benefit of taking the time to learn it.

    /// <summary>
    /// This is a marker interface that indicates that an 
    /// Entity is an Aggregate Root.
    /// </summary>
    public interface IAggregateRoot
    {
    } 


/// <summary>
    /// Contract for Repositories. Entities that have repositories
    /// must be of type IAggregateRoot as only aggregate roots
    /// should have a repository in DDD.
    /// </summary>
    /// <typeparam name="T"></typeparam>
    public interface IRepository<T> where T : IAggregateRoot
    {
        T FindBy(int id);
        IList<T> FindAll();
        void Add(T item);
        void Remove(T item);
        void Remove(int id);
        void Update(T item);
        void Commit();
        void RollbackAllChanges();
    }

Upvotes: 14

Views: 28211

Answers (3)

sloth
sloth

Reputation: 101032

Shouldn't be a problem at all:

public interface IAggregateRoot { }

class Test : IAggregateRoot { }

public interface IRepository<T> where T : IAggregateRoot
{
    // ...
    IList<T> FindAll();
    void Add(T item);
    // ...
 }

class Program
{
    static void Main(string[] args)
    {
        // create Mock
        var m = new Moq.Mock<IRepository<Test>>();

        // some examples
        m.Setup(r => r.Add(Moq.It.IsAny<Test>()));
        m.Setup(r => r.FindAll()).Returns(new List<Test>());
        m.VerifyAll();
    }
}

Upvotes: 17

daryal
daryal

Reputation: 14919

You have to speficy the types, as far as I know there is no direct way of returning generic typed items.

mock = new Mock<IRepository<string>>();    
mock.Setup(x => x.FindAll()).Returns("abc");

Upvotes: 2

Aliostad
Aliostad

Reputation: 81660

I create a dummy concrete class in my tests - or use an existing Entity type.

It might be possible to do it with going through 100 hoops without creating a concrete class, but I do not think it is worth it.

Upvotes: 5

Related Questions