How TDD (Test-Driven-Development) works (Part 2)

Published by admin on

TDD

This is part 2 of the blog series about how TDD (Test-Driven-Development) works. You can refer to the start of the blog series here.

We will continue with the next requirement to evolve our code for String Calculator. First, we will make the test fail for our second requirement and then refactor the Java implementation to make the test pass

Requirement 2: When an empty string is passed as an argument to add() it should return 0

[Java Tests]

package com.gofadi.softwaresolutions.tddtests;

import com.gofadi.softwaresolutions.tdd.StringCalculator;
import org.junit.Assert;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;

import static com.gofadi.softwaresolutions.tdd.StringCalculator.add;

@FixMethodOrder(MethodSorters.DEFAULT)
public class StringCalculatorTests {
    // Requirement 1: The method can take 0, 1 or 2 numbers separated by comma (,).
    // Test 1
    @Test(expected = RuntimeException.class)

    public final void whenMoreThan2NumbersAreUsedThenExceptionIsThrown(){
        add("1,2,3"); // The test will pass as the functionality of throwing the exception is implemented
    }

    // Test 2
   @Test
    public final void when2NumbersAreUsedThenNoExceptionIsThrown() {
        add("1,2");
       Assert.assertTrue(true);
    }

    // Test 3
    @Test(expected = RuntimeException.class)
    public final void whenNonNumberIsUsedThenExceptionIsThrown() {
        add("1,X");
    }

    //Requirement 2: For an empty string the method will return 0
    @Test
    public final void whenEmptyStringIsUsedThenReturnValueIs0() {
        Assert.assertEquals(0, add("")); // In this assertEquals method add method should return 0
    }

}

[Java Implementation]

package com.gofadi.softwaresolutions.tdd;

public class StringCalculator {


    public static int add(final String numbers){
       String[] numbersArray = numbers.split(",");
       

if (numbersArray.length > 2) { // if length of numbers array is greater than 2 then throw a RuntimeException
            throw new RuntimeException("Up to 2 numbers separated by comma (,) are allowed");
        } else {
            for (String number : numbersArray) {
                if (!number.isEmpty()) {
                    Integer.parseInt(number); // If it is not a number, parseInt will throw an exception
                }
            }
        }
        return 1; // Added return statement
    }
}

Explanation: In the refactored code we have changed the return type of the add method from void to int and added the return statement to fulfill the requirement; if an empty string is passed then the method should return 0. To fail the last test you can return any other integer instead of 0.

Requirement 2 Test Failed

[Refactored Code]

public static int add(final String numbers){
       String[] numbersArray = numbers.split(",");
        if (numbersArray.length > 2) { // if length of numbers array is greater than 2 then throw a RuntimeException
            throw new RuntimeException("Up to 2 numbers separated by comma (,) are allowed");
        } else {
            for (String number : numbersArray) {
                if (!number.isEmpty()) {
                    Integer.parseInt(number); // If it is not a number, parseInt will throw an exception
                }
            }
        }
        return 0; // changed return statement from 1 to 0 as expected 
    }
The fourth Test is now Passed after the code is refactored

Requirement 3: Method will return the sum of numbers

[Java Tests]

    // Requirement 3 Method will return the sum of numbers
    // Test 5
    @Test
    public final void whenOneNumberIsUsedThenReturnValueIsThatSameNumber() {
        Assert.assertEquals(3, StringCalculator.add("0"));
    }
    @Test
    public final void whenTwoNumbersAreUsedThenReturnValueIsTheirSum() {
    Assert.assertEquals(3+6, StringCalculator.add("3,6"));
}

[Java Implementation]

public static int add(final String numbers){
       int returnValue = 0;
       String[] numbersArray = numbers.split(",");
/*if length of numbers array is greater than 2 then throw a RuntimeException*/
       if (numbersArray.length > 2) { 
            throw new RuntimeException("Up to 2 numbers separated by comma (,) are allowed");
        } else {
            for (String number : numbersArray) {
                if (!number.isEmpty()) {
                    //Integer.parseInt(number);

// sum the array elements and assign the value to returnValue variable
                    returnValue += Integer.parseInt(number);
                }
            }
        }
        return returnValue; // Return the sum of numbers
    }
All tests passed after adding the functionality of returning the sum of numbers. To be continued 🙂

References:

The example of the string calculator has been taken from the Roy Osherove Katas. Don’t click the link until you’re finished with other parts of this blog series. This exercise is best done when not all requirements are known in advance.


1 Comment

Avatar for admin

Mark · September 7, 2022 at 5:43 pm

Thanks for your blog, nice to read. Do not stop.

Leave a Reply

Avatar placeholder

Your email address will not be published. Required fields are marked *