I came to a code where the method was internally making a call to HttpContext which was hard to unit test, so had to remove such dependency. To do that I could have added the dependencies on the constructor but to avoid excessive refactoring (one step at a time!) I decided to do the inversion of control over the method only.
I decided to just add that object to that method call as a new parameter, after all, such object was being declared inside the method, the idea was to make the call outside of it. With that done, I could make the calls to the method to instantiate the HttpContext as the method itself was doing (no real change, just an IoC as instead of instantiating it inside the method, it was now being instantiated outside, allowing me to mock it).
Initial code and calls:
public void DoSomething() { var context = new HttpContextBase(); //do something more. } public void Caller() { DoSomething(); }
Code after refactoring:
public void DoSomething(HttpContextBase context) { var context = context; // I know this is redundant, just get the idea. //do something more. } public void Caller() { DoSomething(new HttpContextBase()); }
Now I could mock that object and unit test it. Before proceeding, these are some tips when removing a dependency:
- If the dependency is on an object, check if you are using the full object or just one or two of its properties, it will be easier to mock/remove the dependency if we only need to submit those properties.
- If the method is being called at many places you do not need to refactor them all, and the calls to those ones, and the calls to the calls… just initialize the object at the callers to make everything work as it was, compile and check, then you can refactor.
- You could add the dependency to the constructor too, though that would require the method to access a private global object to the class which involves more refactoring, not to mention all the instantiations of that class and possible collisions with other methods inside the class willing to make use of that object too. It can be done and you can even overload the constructor but consider just adding it to the method if it looks like too much refactoring.
- Remember one step at a time, first prepare the method to work with IoC and check everything continues working, then add the new call you were willing to do.
Doing the refactoring using ReSharper
Just as a tip, you can use ReSharper to do this more easily, I did it by adding a new parameter to the signature and then setting its default value to “new HttpContextBase()”, so that ReSharper would add that to the method calls. This case was easy as I only needed to instantiate it. Set the cursor on the Method name, right click > Refactor > Change Signature, or press Ctrl+F6 over the name.