1

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?

2 Answers 2

2

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.

Sign up to request clarification or add additional context in comments.

3 Comments

I didn't want to create a Factory class with an interface that will contain one method that will create my class. Also the idea of a protected virtual method as a factory method gave me the same impression: too much code. My DI is done using public properties (Funq). So this would allow me to have a "default" dependency and be able to change it when testing. It's a "dilemma": it fits with my DI system, but it's the first time I do it.
@graffic: My point is that you've already got a factory class, basically - the delegate. It's as if you've created that interface yourself, but the delegate has more language support. If you think of it as a factory (or converter) then it's an entirely reasonable dependency.
+1 thank you for yor answer. It really helped me to clear my doubts.
0

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.

1 Comment

I use autofixture. But the work needed to make mock objects that "make sense" to the SUT dependencies is like testing again the SUT dependencies through the SUT. Something that I wouldn't like to do. Well... I tried but it was too much work

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.