Question

The problem

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

  • I have a SUT. (a good thing to have :P )
  • 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?

Was it helpful?

Solution

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.

OTHER TIPS

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top