© We Can Code IT, LLC
Git Bash
cd
into your eclipse workspacemkdir fizzbuzz
cd
into the fizzbuzz directorycurl https://raw.githubusercontent.com/WeCanCodeIT/gradle-scripts/master/basic-junit/build.gradle --output build.gradle
gradle eclipse
Eclipse
and import existing project into workspacefizzbuzz
in src/test/java
FizzBuzzTest
in your new packagepackage fizzbuzz;
import static org.junit.Assert.assertEquals;
import org.junit.Test;
public class FizzBuzzTest {
@Test
public void shouldReturnOneAsString() {
// Arrange
FizzBuzz underTest = new Fizzbuzz();
// Act
String actual = underTest.parse(1);
// Assert
assertEquals("1", actual);
}
}
So all of our failures at this point are compilation failures. To fix these, let's let our IDE fix some things for us…
So now we have the following generated class in src/main/java
and in our fizzbuzz
package.
package fizzbuzz;
public class FizzBuzz {
public String parse(int i) {
// TODO Auto-generated method stub
return null;
}
}
Now run your tests to see this one fail (<ctrl> + <R>).
Now, we do the SIMPLEST thing to make the test pas. In this case…
package fizzbuzz;
public class FizzBuzz {
public String parse(int i) {
return "1";
}
}
Remember, never write more code than you need to make the test pass. Even if you know how the code may change in the future. Be creative with your tests and let them dictate how your code should work.
Now, run your test to see it passing!
Now that we have gotten to green in the red -> green -> refactor cycle, it's time to refactor! Remember, refactoring can take the form of properly naming things, deleting unnecessary code, removing duplication, or anything else that generally makes our code cleaner.
package fizzbuzz;
public class FizzBuzz {
public String parse(int number) {
return "1";
}
}
This may seem like a small detail now, but proper naming conventions are a tremendous part of clean code. Never neglect the impact a good namespacing convention can have on a codebase.
Now that we've got a passing test for 1, let's write a test for 2.
public class FizzBuzzTest {
...
@Test
public void shouldReturnTwoAsString() {
// Arrange
FizzBuzz underTest = new FizzBuzz();
// Act
String actual = underTest.parse(2);
// Assert
assertEquals("2", actual);
}
}
Run this test to see it fail.
So let's change our class under test to make this test pass…
package fizzbuzz;
public class FizzBuzz {
public String parse(int number) {
if (number == 1) {
return "1";
}
return "2";
}
}
Remember, since return
is a break statement, we will never run the risk of returning two outcomes from the same method. Run your tests to see them pass.
Time to make our code cleaner again. Now let's take a look at the logic of our method and think about how we can make it cleaner. At this point it's pretty clear that we are just returning a String
version of whatever int
we pass in. Let's make our method do that instead…
package fizzbuzz;
public class FizzBuzz {
public String parse(int number) {
return "" + number;
}
}
We're using string concatenation to force the result to be a String
!
Time for our third test!
@Test
public void shouldReturnFizzForThree() {
// Arrange
FizzBuzz underTest = new FizzBuzz();
// Act
String actual = underTest.parse(3);
// Assert
assertEquals("Fizz", actual);
}
Run this to see the fail.
Remember to do the simplest thing to make the test pass.
package fizzbuzz;
public class FizzBuzz {
public String parse(int number) {
if (number == 3) {
return "Fizz";
}
return "" + number;
}
}
Since there really isn't anything to refactor, it's time to turn red again! So, for our next test, we are going to choose 5.
@Test
public void shouldReturnBuzzForFive() {
// Arrange
FizzBuzz underTest = new FizzBuzz();
// Act
String actual = underTest.parse(5);
// Assert
assertEquals("Buzz", actual);
}
Why 5 and not 4?
package fizzbuzz;
public class FizzBuzz {
public String parse(int number) {
if (number == 5) {
return "Buzz";
}
if (number == 3) {
return "Fizz";
}
return "" + number;
}
}
We now have a passing test for 5!
Time to continue on our testing journey…
@Test
public void shouldReturnFizzForSix() {
// Arrange
FizzBuzz underTest = new FizzBuzz();
// Act
String actual = underTest.parse(6);
// Assert
assertEquals("Fizz", actual);
}
This gets us failing. Let continue on the simplest road to passing.
package fizzbuzz;
public class FizzBuzz {
public String parse(int number) {
if (number == 5) {
return "Buzz";
}
if (number == 3 || number == 6) {
return "Fizz";
}
return "" + number;
}
}
Now let's examine our parse
method and see how we can make this logic a little more clear
package fizzbuzz;
public class FizzBuzz {
public String parse(int number) {
if (number == 5) {
return "Buzz";
}
if (number % 3 == 0) {
return "Fizz";
}
return "" + number;
}
}
So now we're using the modulus operator to see if the number we have is evenly divisible by 3. We do this by checking to see if zero is the remainder when we divide by 3.
Time to continue using this same logic to figure out the remaining numbers to test! Which numbers make sense to test? Which do we have enough confidence to skip at this point?