Search code examples
c#inheritancecastingmoq

Moq: Mocking an interface of abstract base class of a controller


My problem: I want to unittest a controller. This controller has a constructor that includes a repository. Repositories are named like SomethingRepository. SomethingRepository inherits from abstract class BaseRepository<ReadModel, Dto, Filter>. BaseRepository inherits from interface IRepository<ReadModel, Dto, Filter>.

When I want to mock SomethingRepository using Moq, I will need to mock the interface, as far as I understand, since mocking a class will demand an empty constructor which SomethingRepository and BaseRepository don't have. (I don't want to add one)

So, I have tried

Mock.Of<
   IRepository<
       SomeReadModel,
       SomeDto,
       SomeFilter>
>();

However, when I try to assign this mock (with a cast) to a variable of type SomethingRepository, I get an InvalidCastException:

System.InvalidCastException : Unable to cast object of type 'Castle.Proxies.IRepository`3Proxy' to type 'Repositories.SomeRepository'.

How do I fix this?


Solution

  • The constructor of SomeController has the following signature which takes in an IRepository:

    public SomeController(IRepository<ReadModel, Dto, Filter> repository)
        : base(repository)
    

    In my test, I was trying to do cast this to the concrete repository:

    SomeRepository repository = (SomeRepository) Mock.of<IRepository<ReadModel, Dto, Filter>>;
    
    new SomeController(repository);
    

    Instead, I need to pass the repository interface into the controller, not the concrete class:

    IRepository<Something> repository = Mock.of<IRepository<ReadModel, Dto, Filter>>;
    
    new SomeController(repository);