The problem
Let’s “draw” a picture of the situation:
- I have a SUT. (a good thing to have 😛 )
- I can inject some dependencies on my SUT.
- In a method I do a: new OtherClass(ParametersObtainedFromDependancies).
- I want to unit test that method in my SUT without handling the complexity of creating mock object that make sense for OtherClass to work correctly. This will imply to test OtherClass.
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?
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
OtherClasswhen 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
IAuthenticatorinterface which, when provided with a username and password will return aUserProfile? 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.