简体   繁体   English

Moq: Mocking 一个controller的抽象基类class的接口

[英]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.我的问题:我想对 controller 进行单元测试。这个 controller 有一个包含存储库的构造函数。 Repositories are named like SomethingRepository .存储库的名称类似于SomethingRepository SomethingRepository inherits from abstract class BaseRepository<ReadModel, Dto, Filter> . SomethingRepository继承自抽象 class BaseRepository<ReadModel, Dto, Filter> BaseRepository inherits from interface IRepository<ReadModel, Dto, Filter> . BaseRepository继承自接口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.当我想使用 Moq 模拟SomethingRepository时,我需要模拟接口,据我所知,因为 mocking 和 class 将需要一个SomethingRepositoryBaseRepository没有的空构造函数。 (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 :但是,当我尝试将此模拟(带有强制转换)分配给SomethingRepository类型的变量时,我得到一个InvalidCastException

System.InvalidCastException: Unable to cast object of type 'Castle.Proxies.IRepository`3Proxy' to type 'Repositories.SomeRepository'. System.InvalidCastException:无法将类型为“Castle.Proxies.IRepository`3Proxy”的 object 转换为类型“Repositories.SomeRepository”。

How do I fix this?我该如何解决?

Every SomeRepository is a IRepository<SomeReadModel, SomeDto, SomeFilter> , but not every IRepository<SomeReadModel, SomeDto, SomeFilter> is a SomeRepository .每个SomeRepository都是IRepository<SomeReadModel, SomeDto, SomeFilter> ,但不是每个IRepository<SomeReadModel, SomeDto, SomeFilter>都是SomeRepository If your controller injects a SomeRepository , you have to provide something which is (or inherits from) the SomeRepository class.如果你的 controller 注入了一个SomeRepository ,你必须提供一些是(或继承自) SomeRepository class 的东西。

The solution is to change your controller so that it injects a IRepository<SomeReadModel, SomeDto, SomeFilter> instead.解决方案是更改您的 controller 以便它注入IRepository<SomeReadModel, SomeDto, SomeFilter>

The constructor of SomeController has the following signature which takes in an IRepository : SomeController的构造函数具有以下接受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:相反,我需要将存储库接口传递到 controller,而不是具体的 class:

IRepository<Something> repository = Mock.of<IRepository<ReadModel, Dto, Filter>>;

new SomeController(repository);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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