When mocking a class with Moq, how can I CallBase for just specific methods?

前端 未结 3 1043
清歌不尽
清歌不尽 2020-12-05 22:55

I really appreciate Moq\'s Loose mocking behaviour that returns default values when no expectations are set. It\'s convenient and saves me code, and it also act

3条回答
  •  南笙
    南笙 (楼主)
    2020-12-05 23:16

    Since nobody's answered this question for ages and I think it deserves an answer, I'm going to focus on the highest-level question you asked: how to keep these benefits when the method under test happens to be virtual.

    Quick answer: you can't do it with Moq, or at least not directly. But, you can do it.

    Let's say that you have two aspects of behaviour, where aspect A is virtual and aspect B is not. That pretty much mirrors what you've got in your class. B can use other methods or not; it's up to you.

    At the moment, your class Foo is doing two things - both A and B. I can tell that they're separate responsibilities just because you want to mock A out and test B on its own.

    Instead of trying to mock out the virtual method without mocking out anything else, you can:

    • move behaviour A into a separate class
    • dependency inject the new class with A into Foo through Foo's constructor
    • invoke that class from B.

    Now you can mock A, and still call the real code for B..N without actually invoking the real A. You can either keep A virtual or access it through an interface and mock that. This is in line with the Single Responsibility Principle, too.

    You can cascade constructors with Foo - make the constructor Foo() call the constructor Foo(new A()) - so you don't even need a dependency injection framework to do this.

    Hope this helps!

提交回复
热议问题