graffic
graffic

Reputation: 1412

Using a delegate as "factory method" for unit testing in C#

The problem

Let's "draw" a picture of the situation:

My solution to this was a factory method using a delegate:

public Func<OtherClass,Param1Type> GetOtherClass = 
       (param1) => new OtherClass(param1);

The bad: it's public. You could think on it as an optional dependency that you can override if need. But anyway, public smells.

The good: I don't need to create a MyTestSUT that will override this method, or even use a mock on the SUT to override that method.

Question

Is there any better solution? Is this correct?

Upvotes: 1

Views: 863

Answers (2)

the_drow
the_drow

Reputation: 19181

It sounds like you want to use something similar to AutoFixture with it's AutoMoq customization enabled. This will enable you to mock all or some of your public fields in your SUT along with your other constructor parameters if you wish.

Upvotes: 0

Jon Skeet
Jon Skeet

Reputation: 1500585

Why have you made it a public field? It sounds like it's basically a dependency like any other: you want something which will provide you with an OtherClass when you give it some other values. Why not just make it a constructor parameter like other dependencies (or however you're doing the rest of your dependency injection)?

You can always provide a constructor overload without this parameter which delegates to the longer one, if you want to. That's how I normally provide "default" dependency implementations.

To put it another way: how is this logically different from (say) an IAuthenticator interface which, when provided with a username and password will return a UserProfile? You happen to be using a delegate as a short-cut to avoid declaring the interface, but that's just a detail IMO. You may find that as time goes on, you actually want to put more smarts in the "providing" part - e.g. caching.

Upvotes: 2

Related Questions