4

How to write a NUnit test for a method like this. Does this method itself warrant refactoring? What is the best approach to deal with scenarios like this in leagacy code?

         public bool DoXYZ()
            {
                ABC abc= new ABC()
                XYZ xyz = new XYZ();
                if (xyz .IsSomeCondition(Session.SessionID))
                { return false; }
                else
                { return abc.IsSomeOtherCondition(SessionID.SessionID); }
            }
3
  • 2
    This question cannot be answered without showing a bit more code. What is Session? What is SessionID? How does the containing class look like? Commented Jan 19, 2011 at 17:52
  • You first need to know what does this class do. Knowing that you can write a Test to verify that this method is doing what it is suposed to do. Btw, I agree with the others, you should use some Dependency Injection so you can mock those ABC and XYZ. Commented Jan 19, 2011 at 18:07
  • You should definately read the following book: amazon.com/Working-Effectively-Legacy-Michael-Feathers/dp/… Commented Jan 19, 2011 at 21:01

4 Answers 4

4

You will probably need to refactor it to introduce hooks for dependency injection. For example, the class that contains the DoXYZ method can get new properties for ABC and XYZ. These properties could default to instances of ABC and XYZ, but in the unit tests could be replaced by mock versions.

And if you prefer to use IoC, this approach supports that as well

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

Comments

1

I would definitely refactor to inject the session id via a parameter - otherwise you'll have to create the session manually.

Can it be made static? Looks like it, particularly if you inject sessionid.

Also, you're implementing a (short) command dispatcher, which is generally considered an anti-pattern, compared to IoC (see Joel Martinez' answer above).

Comments

1

You have two choices:

  • Refactor your code and use dependency injection as Joel and Chris suggested. This can involve a lot of work but it will make your code clean and easily testable.
  • Use advanced framework for mocking non injected dependencies as asked in this question.

The way to go in big legacy code is probably using both approaches.

You can also check this article from MSDN magazine.

1 Comment

Interesting article...I haven't heard of Pex before.
0

Given the obfuscated code in the question, I can only offer a few pointers

  • I see 2 paths - so 2 unit tests needed minimum.
  • creating collaborators within a method is usually troublesome down the road. Pass in dependencies as ctor / method parameters. This allows you to derive a fake and manipulate branching (e.g. make xyz.IsSomeCondition return false for this test). If ABC and XYZ are simple classes that are easy to setup, then it may not be an immediate problem.. you could live without the Extract Parameter refactoring for now.
  • extract sessionId into a parameter to eliminate static (global) variable access, which normally retain their previous values causing dependencies between tests

.

public bool DoXYZ(ABC abc, XYZ xyz, Guid sessionId) 
{    if (xyz.IsSomeCondition(sessionId))    
        return false; 

     return abc.IsSomeOtherCondition(sessionId);  
}

Comments

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.