Take the 2-minute tour ×
Programmers Stack Exchange is a question and answer site for professional programmers interested in conceptual questions about software development. It's 100% free, no registration required.

I was recently discussing with some friends which of the following 2 methods is best to stub return results or calls to methods inside same class from methods inside same class.

This is a very simplified example. In reality the functions are much more complex.

Example:

public class MyClass
{
     public bool FunctionA()
     {
         return FunctionB() % 2 == 0;
     }

     protected int FunctionB()
     {
         return new Random().Next();
     }
}

So to test this we have 2 methods.

Method 1: Use Functions and Actions to replace functionality of the methods. Example:

public class MyClass
{
     public Func<int> FunctionB { get; set; }

     public MyClass()
     {
         FunctionB = FunctionBImpl;
     }

     public bool FunctionA()
     {
         return FunctionB() % 2 == 0;
     }

     protected int FunctionBImpl()
     {
         return new Random().Next();
     }
}

[TestClass]
public class MyClassTests
{
    private MyClass _subject;

    [TestInitialize]
    public void Initialize()
    {
        _subject = new MyClass();
    }

    [TestMethod]
    public void FunctionA_WhenNumberIsOdd_ReturnsTrue()
    {
        _subject.FunctionB = () => 1;

        var result = _subject.FunctionA();

        Assert.IsFalse(result);
    }
}

Method 2: Make members virtual, derive class and in derived class use Functions and Actions to replace functionality Example:

public class MyClass
{     
     public bool FunctionA()
     {
         return FunctionB() % 2 == 0;
     }

     protected virtual int FunctionB()
     {
         return new Random().Next();
     }
}

public class TestableMyClass
{
     public Func<int> FunctionBFunc { get; set; }

     public MyClass()
     {
         FunctionBFunc = base.FunctionB;
     }

     protected override int FunctionB()
     {
         return FunctionBFunc();
     }
}

[TestClass]
public class MyClassTests
{
    private TestableMyClass _subject;

    [TestInitialize]
    public void Initialize()
    {
        _subject = new TestableMyClass();
    }

    [TestMethod]
    public void FunctionA_WhenNumberIsOdd_ReturnsTrue()
    {
        _subject.FunctionBFunc = () => 1;

        var result = _subject.FunctionA();

        Assert.IsFalse(result);
    }
}

I want to know wich is better and also WHY ?

Update: NOTE: FunctionB can also be public

share|improve this question

migrated from codereview.stackexchange.com Feb 27 '13 at 16:28

This question came from our site for peer programmer code reviews.

    
Your example is simple, but not exactly correct. FunctionA returns a bool but only sets a local variable x and doesn't return anything. –  E-Man Feb 26 '13 at 16:41
    
Thanks for pointing that out. Edited post accordingly –  tranceru1 Feb 26 '13 at 18:28
1  
In this particular example, FunctionB can be public static but in a different class. –  Leonid Feb 26 '13 at 19:27
    
For Code Review, you are expected to post actual code not a simplified version of it. See the FAQ. As its stands, you are asking a specific question not looking for a code review. –  Winston Ewert Feb 27 '13 at 16:28
1  
FunctionB is broken-by-design. new Random().Next() is almost always wrong. You should inject the instance of Random. (Random is also a badly designed class, which can cause a few additional problems) –  CodesInChaos Feb 27 '13 at 16:51

3 Answers 3

up vote 12 down vote accepted

Edited following original poster update.

Disclaimer : not a C# programmer (mostly Java or Ruby). My answer would be : I would not test it at all, and I do not think you should.

The longer version is : private/protected methods are not parts of the API, they are basically implementation choices, that you can decide to review, update or throw away completely without any impact on the outside.

I suppose you have a test on FunctionA(), which is the part of the class that is visible from the external world. It should be the only one that has a contract to implement (and that could be tested). Your private/protected method has no contract to fulfil and/or test.

See a related discussion there : http://stackoverflow.com/questions/105007/should-i-test-private-methods-or-only-public-ones

Following the comment, if FunctionB is public, I'll simply test both using unit test. You may think that the test of FunctionA is not totally "unit" (as it call FunctionB), but I would not be too worried by that : if FunctionB test works but not FunctionA test, it means clearly that the problem is not in the subdomain of FunctionB, which is good enough for me as a discriminator.

If you really want to be able to totally separate the two tests, I would use some kind of mocking technique to mock FunctionB when testing FunctionA (typically, return a fixed known correct value). I lack the C# ecosystem knowledge to advice a specific mocking library, but you may look at this question.

share|improve this answer
2  
Completely agree with @Martin answer. When you write unit tests for class you should not test methods. What you're testing is a class behavior, that the contract (the declaration what class is supposed to do) is satisfied. So, your unit tests should cover all the requirements exposed for this class (using public methods/properties), including exceptional cases –  almaz Feb 26 '13 at 16:29
    
Hello, thanks for the response, but it didn't answer my question. I doesn't matter if FunctionB was private / protected. It can also be public and still be called from FunctionA. –  tranceru1 Feb 26 '13 at 16:32
    
The most common way to handle this problem, without redesigning the base class, is to subclass MyClass and override the method with the functionality you want to stub. It might also be a good idea to update your question to include that FunctionB could be public. –  E-Man Feb 26 '13 at 16:50
    
When it comes to unit testing and TDD you would write your test first, make your test pass all inside your public method. Once you get it passing you can either move on or refactor. Refactoring gives you private methods.. Now In this particular case you would would want to look into dependency injection. Find a way that you put FunctionB into your parameter. This way you can force feed FunctionA with any known values to and assert certain values back. –  Robert Snyder Feb 26 '13 at 18:45
2  
The fact that FunctionA calls FunctionB is an irrelevant detail from a unit testing perspective. If the tests for FunctionA are written correctly, it is an implementation detail that could be refactored-out later without breaking tests (so long as the overall behavior of FunctionA is left unchanged). The real issue is that FunctionB's retrieval of a random number needs to be done with an injected object, so that you can use a mock during testing to ensure that a well-known number is returned. This allows you test well-known inputs/outputs. –  Dan Lyons Feb 27 '13 at 18:27

Adding on to what Martin points out,

If your method is private/protected - do not test it. It is internal to the class and should not be accessed outside the class.

In both the approaches that you mention, I have these concerns -

Method 1 - This actually changes the class under test's behaviour in the test.

Method 2 - This actually does not test the production code, instead tests another implementation.

In the problem stated, I see that the only logic of A is to see if the output of FunctionB is even. Although illustrative, FunctionB gives Random value, which is tough to test.

I expect a realistic scenario where we can setup MyClass such that we know what FunctionB would return. Then our expected result is known, we can call FunctionA and assert on the actual result.

share|improve this answer
2  
protected is almost the same as public. Only private and internal are implementation details. –  CodesInChaos Feb 27 '13 at 17:08
    
@codeinchaos - I am curious here. For a test, protected methods are 'private' unless you modify assembly attributes. Only derived types have access to protected members. With the exception of virtual, I don't see why protected should be treated similar to public from a test. could you elaborate please? –  Srikanth Venugopalan Feb 28 '13 at 1:37
    
Since those derived classes can be in different assemblies, they're exposed to third party code, and thus part of the public surface of your class. To test them, you can either make them internal protected, use a private reflection helper, or create a derived class in your test project. –  CodesInChaos Feb 28 '13 at 8:21
    
@CodesInChaos, agreed that derived class can be in different assemblies, but the scope is still restricted to the base and derived types. Modifying the access modifier just to make it testable is something that I am a bit nervous about. I have done it, but it seems to be an antipattern to me. –  Srikanth Venugopalan Feb 28 '13 at 8:25

I subscribe to the theory that if a function is important to test, or is important to replace, it is important enough to not be a private implementation detail of the class under test, but to be a public implementation detail of a different class.

So if I am in a scenario where I have

class A 
{
     public B C()
     {
         D();
     }

     private E D();
     {
         // i actually want to control what this produces when I test C()
         // or this is important enough to test on its own
         // and, typically, both of the above
     }
}

Then I am going to refactor.

class A 
{
     ICollaborator collaborator;

     public A(ICollaborator collaborator)
     {
         this.collaborator = collaborator;
     }

     public B C()
     {
         collaborator.D();
     }
}

Now I have a scenario where D() is independently testable, and fully replaceable.

As a means of organization, my collaborator might not live at the same namespace level. For example, if A is in FooCorp.BLL, then my collaborator might be another layer deep, as in FooCorp.BLL.Collaborators (or whatever name is appropriate). My collaborator might further only be visible inside the assembly via the internal access modifier, which I would then also expose to my unit testing project(s) via the InternalsVisibleTo assembly attribute. The takeaway is that you can still keep your API clean, as far as callers are concerned, while producing verifiable code.

share|improve this answer
    
Yes if ICollaborator needs several methods. If you have an object who's only job is to wrap a single method I'd rather see it replaced with a delegate though. –  jk. Feb 28 '13 at 7:39
    
You'd have to decide if a named delegate make sense or if an interface makes sense, and I won't decide for you. Personally, I am not averse to single (public) method classes. The smaller the better, as they become increasingly easy to understand. –  Anthony Pegram Feb 28 '13 at 16:34

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.