Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it a code smell for one method to depend on another?

I am refactoring a class so that the code is testable (using NUnit and RhinoMocks as testing and isolations frameworks) and have found that I have found myself with a method is dependent on another (i.e. it depends on something which is created by that other method). Something like the following:

public class Impersonator
{
    private ImpersonationContext _context;

    public void Impersonate()
    {
        ...
        _context = GetContext();
        ...
    }

    public void UndoImpersonation()
    {
        if (_context != null)
            _someDepend.Undo();
    }
}

Which means that to test UndoImpersonation, I need to set it up by calling Impersonate (Impersonate already has several unit tests to verify its behaviour). This smells bad to me but in some sense it makes sense from the point of view of the code that calls into this class:

public void ExerciseClassToTest(Impersonator c)
{
     try
     {
         if (NeedImpersonation())
         {
             c.Impersonate();
         }
         ...
     }
     finally
     {
         c.UndoImpersonation();
     }
}

I wouldn't have worked this out if I didn't try to write a unit test for UndoImpersonation and found myself having to set up the test by calling the other public method. So, is this a bad smell and if so how can I work around it?

like image 453
jpoh Avatar asked Jul 29 '09 08:07

jpoh


2 Answers

Code smell has got to be one of the most vague terms I have ever encountered in the programming world. For a group of people that pride themselves on engineering principles, it ranks right up there in terms of unmeasurable rubbish, and about as useless a measure, as LOCs per day for programmer efficiency.

Anyway, that's my rant, thanks for listening :-)

To answer your specific question, I don't believe this is a problem. If you test something that has pre-conditions, you need to ensure the pre-conditions have been set up first for the given test case.

One of the tests should be what happens when you call it without first setting up the pre-conditions - it should either fail gracefully or set up it's own pre-condition if the caller hasn't bothered to do so.

like image 197
paxdiablo Avatar answered Nov 02 '22 08:11

paxdiablo


Well, there is a bit too little context to tell, it looks like _someDepend should be initalized in the constructor.

Initializing fields in an instance method is a big NO for me. A class should be fully usable (i.e. all methods work) as soon as it is constructed; so the constructor(s) should initialize all instance variables. See e.g. the page on single step construction in Ward Cunningham's wiki.

The reason initializing fields in an instance method is bad is mainly that it imposes an implicit ordering on how you can call methods. In your case, TheMethodIWantToTest will do different things depending on whether DoStuff was called first. This is generally not something a user of your class would expect, so it's bad :-(.

That said, sometimes this kind of coupling may be unavoidable (e.g. if one method acquires a resource such as a file handle, and another method is needed to release it). But even that should be handled within one method if possible.

What applies to your case is hard to tell without more context.

like image 39
sleske Avatar answered Nov 02 '22 08:11

sleske