Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Tomek Kaczanowski - Practical Unit Testing with JUnit and Mockito - 2013.pdf
Скачиваний:
228
Добавлен:
07.03.2016
Размер:
6.59 Mб
Скачать

Chapter 4. Test Driven Development

I’ll leave it to you to decide whether this way of code-teasing yourself is something you want to practice. I would encourage you to give it a try, because this kind of exercise will help to sharpen your understanding of what good tests really involve.

4.5.6. More Test Cases

The constructor seems to work fine, …at least for this one value! We should add tests for more values, and also make the constructor throw an exception if an inappropriate number of wins is passed to the constructor (see Section 6.1). We will use parameterized tests (discussed in Section 3.6) in both cases.

The following code snippets illustrate both cases:

Listing 4.7. Testing valid values using parameterized test

public Object[] nbOfGamesWon() { return $(0, 1, 2);

}

@Test

@Parameters(method = "nbOfGamesWon")

public void constructorShouldSetGamesWon(int nbOfGamesWon) { FootballTeam team = new FootballTeam(nbOfGamesWon); assertEquals(nbOfGamesWon + " games passed to constructor, " +

"but " + team.getGamesWon() + " were returned", nbOfGamesWon, team.getGamesWon());

}

Listing 4.8. Testing invalid values using parameterized test

public Object[] illegalNbOfGamesWon() { return $(-10, -1);

}

@Test(expected = IllegalArgumentException.class) @Parameters(method = "illegalNbOfGamesWon")

public void constructorShouldThrowExceptionForIllegalGamesNb( int illegalNbOfGames) {

new FootballTeam(illegalNbOfGames);

}

But is It Comparable?

The constructor works fine. Now we can move on to the main problem: that is, to the comparing of football teams. First of all, we have decided that we are going to use the Comparable interface. This is an important decision which will influence not only the implementation of this class but also its API and expected behaviour. If FootballTeam is comparable, then the client can expect that once he has put a few teams into a collection, he will be able to use the Collections.sort() method to order them. If so, then there should be a test for this behaviour. The only one I can think of is the following:

53

Chapter 4. Test Driven Development

Listing 4.9. Is FootballTeam comparable?

private static final int ANY_NUMBER = 123;

@Test

public void shouldBePossibleToCompareTeams() { FootballTeam team = new FootballTeam(ANY_NUMBER);

assertTrue(team instanceof Comparable, "FootballTeam should implement Comparable");

}

This is a rather uncommon test: I rarely write tests which use an instanceof operator. However, in this case it seems legitimate, as it covers an important characteristic of the FootballTeam class, required by its clients.

Please note the name of the static value passed to the constructor: ANY_NUMBER. That indicates that this argument is not important. The real value of the argument does not influence the test in any way.

The test will fail. Your IDE is surely capable of fixing the code. After the IDE has generated the default implementation of the compareTo() method, the FootballTeam class will look like this:

Listing 4.10. FootballTeam implements Comparable interface

public class FootballTeam implements Comparable<FootballTeam> { private int gamesWon;

public FootballTeam(int gamesWon) { this.gamesWon = gamesWon;

}

public int getGamesWon() { return gamesWon;

}

@Override

public int compareTo(FootballTeam o) { return 0;

}

}

Rerun the test to check that it passes now. It does. Good.

Before we move on to the next tests, let us make one thing clear: it is essential to run the whole test suite, and NOT only the last failed tests. Make sure that while working on a certain feature you do not break other features. Remember, always run all unit tests you have. If they are really "unit", they will run fast - no problem running them often, right?

Comparison Tests

If you are not familiar with the Comparable interface, please take a look at the description of

the Comparable.compareTo() method Javadocs.

Now let us write the first comparison test. The idea is simple: take two teams with different numbers of wins and compare them.

54

Chapter 4. Test Driven Development

Listing 4.11. The first comparison test

@Test

public void teamsWithMoreMatchesWonShouldBeGreater() { FootballTeam team_2 = new FootballTeam(2); FootballTeam team_3 = new FootballTeam(3);

assertTrue(team_3.compareTo(team_2) > 0);

}

After running, the test will fail. Once again, the error message is cryptic, and needs to be updated. After it has been changed, the failed tests can print something more informative:

Listing 4.12. Comparison test failure

java.lang.AssertionError:

team with 3 games won should be ranked before the team with 2 games won at org.junit.Assert.fail(Assert.java:93)

at org.junit.Assert.assertTrue(Assert.java:43) at com.practicalunittesting.FootballTeamTest

.teamWithMoreMatchesWonShouldBeGreater(FootballTeamComparatorTest.java:14)

Let us fix the production code, but do not implement more than the test requires us to! The compareTo() method shown below is a minimal (reasonable) implementation which will make the test pass:

Listing 4.13. compareTo() method recognizes better teams

@Override

public int compareTo(FootballTeam o) { if (gamesWon > o.getGamesWon()) {

return 1;

}

return 0;

}

After running all tests, we should:

refactor (e.g. change the o variable to otherTeam),

rerun the tests so we are sure nothing is broken,

and, finally, proceed with the next test.

Listing 4.14. Another comparison test

@Test

public void teamsWithLessMatchesWonShouldBeLesser() { FootballTeam team_2 = new FootballTeam(2); FootballTeam team_3 = new FootballTeam(3);

assertTrue("team with " + team_2.getGamesWon()

+" games won should be ranked after the team with "

+team_3.getGamesWon() + " games won",

team_2.compareTo(team_3) < 0);

}

Run, see it fail, then introduce changes to the FootballTeam class so the tests pass. The implementation which makes this test pass is, once again, trivial:

55

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]