Skip to content
This repository was archived by the owner on Jun 30, 2023. It is now read-only.
This repository was archived by the owner on Jun 30, 2023. It is now read-only.

To have an interface Mock use existing implementation logic, devs should be able to provide an implementation class #42

@craigfowler

Description

@craigfowler

This is a feature request for new Moq functionality. Something which comes up from time to time in testing is a scenario when I want to create an interface-based Mock object and - by default - I want its functionality to behave as if it were a real instance of an implementation class for that interface. I don't want to just provide an instance of that class though, because I also want to use some of Moq's functionality such as writing one or more setups or using a Verify to verify that a method was called with the correct params.

In this scenario what I would like would be a way to tell Mock:

Hey, I want a mock for interface IFoo, but for any functionality which I haven't explicitly set up, could you just behave as if you were an instance of ConcreteFoo?

In many ways, this is like setting CallBase to true for a class-based Mock, except that for interfaces, the developer needs to provide an impl. I'd expect to see it work in a very similar way; the matching functionality from the provided concrete impl would be executed and used, unless a setup matches the call to the mock.

Suggested syntax

Here's some suggested syntaxes and overloads for the functionality. The names UseDefaultImplementation and UseDefaultImplementationType are 100% up for grabs, I'm not precious about them at all.

In this case/overload, the dev must pass an instance of IFoo to the mock object directly. This function could reasonably use a generic type constraint to ensure that the impl instance passed is of type IFoo.

var mockObj = new Mock<IFoo>();
var defaultImpl = new ConcreteFoo();
mockObj.UseDefaultImplementation(defaultImpl);

In this case/overload, the dev indicates the implementation type to use and Moq takes control of creating the instance, perhaps just via Activator.CreateInstance, or via a generic type constraint on new(). It would also be totally reasonable to have a generic type constraint on IFoo here.

var mockObj = new Mock<IFoo>();
mockObj.UseDefaultImplementationType<ConcreteFoo>();

This overload would be functionally identical to the above, except non-generic. Obviously, the compiler wouldn't be able to use generic type constraints to ensure you provided a sane type.

var mockObj = new Mock<IFoo>();
mockObj.UseDefaultImplementationType(typeof(ConcreteFoo));

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions