Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Do I have to fake a value object in my unit test

I have written a class using TDD containing a method (method under test) which takes a simple value object as a parameter (range).

Code:

The method under test looks like this:

public List<string> In(IRange range)
{
     var result = new List<string>();
     for (int i = range.From; i <= range.To; i++)
     {
          //...
     }
     return result;
}

Furthermore I have a unit test to verify my method under test:

[TestMethod]
public void In_SimpleNumbers_ReturnsNumbersAsList()
{
    var range = CreateRange(1, 2);
    var expected = new List<string>() { "1", "2" };
    var result = fizzbuzz.In(range);
    CollectionAssert.AreEqual(expected, result);
}

private IRange CreateRange(int from, int to)
{
    return new Fakes.StubIRange() 
    { 
        FromGet = () => { return from; }, 
        ToGet = () => { return to; } 
    };
}

Question:

I have read Roy Osherove's book on unit testing ("The Art of Unit Testing"). In there he says

"external dependencies (filesystem, time, memory etc.) should be replaced by stubs"

What does he mean by external dependency? Is my value object (range) also an external dependency which should be faked? Should I fake all dependencies a class have?

Can someone give me an advice

like image 986
MUG4N Avatar asked May 02 '13 11:05

MUG4N


1 Answers

TL;DR

Do the simplest thing possible that solves your problem.


The longer I have been using TDD, the more I appreciate the value of being pragmatic. Writing super-duper isolated unit tests is not a value unto itself. The tests are there to help you write high quality code that is easy to understand and solves the right problem.

Adding an interface for the range class is a good idea if you have the need to be able to switch to another concrete range implementation without having to modify the code which depends on it.

However, if you do not have that need adding an interface serves no real purpose, but it does add some complexity, which actually takes you further from the goal of writing easy to understand code which solves the problem.

Be careful not to think to much about what might change in the future. YAGNI is a good principle to follow. If you have been doing TDD you won't have any problems refactoring the code if an actual need occurs in the future, since you have solid tests to rely on.

In general terms I would not consider a proper Value Object to be a dependency. If it is complex enough that you feel uncomfortable letting other code use it when under test it sounds like it is actually more like a service.

like image 199
Erik Öjebo Avatar answered Sep 21 '22 21:09

Erik Öjebo