unit-testingtdd

TDD procedure for writing tests for a function with multiple execution paths


While following test driven development, I came across a function that I need to write which is similar to the following:

public MyClass DoSomething(string value)
{
    SomeClass existCheck = repository.Get(value);

    if(existCheck == null)
        throw new InvalidOperationException("SomeClass must exist to do something");

    if(existCheck.MyClass != null)
        return existCheck.MyClass;

    MyClass myClass = new MyClass()
    {
        // create object
    };

    return myClass;
}

Using TDD, I would need to write seperate tests to

  1. Assert that the exception is thrown
  2. Assert that an existing SomeClass is returned
  3. Assert that a new MyClass is returned

Do I write all three tests first then code them or do I write each test, then code the functionality in the function required for the test to pass and then write the next test and the code the functionality etc.?


Solution

  • I've always believed that with TDD you should take baby steps, with the Red-light Green-light approach. I would proceed in the following steps:

    1. Write a test for the existCheck == null scenario, which will fail (Red-light)
    2. Do the necessary work for scenario 1 to succeed, and re-run the test (green-light)
    3. Write a second test for the existCheck.MyClass != null scenario, which will fail. You could often do this by copying your first test and modifying it.
    4. Modify the method so that both tests 1 and 2 pass.
    5. Repeat steps 3 and 4 for the final execution path.

    Generally, I find you can progress with a test as the method proceeds, and then copy the test each time you reach a branch, tailoring each test to each differing path.