This example is picked from Martin Fowler's "Refactoring" book, chapter 1, "Refactoring, a First Example".
The charge for renting a movie depends on both the type of movie and how long the movie is rented. Customers can also earn frequent renter points, depending on whether the film is a new release.
videostore.Pricing | |||
movieCategory | daysRented | charge() | frequentRenterPoints() |
videostore.RegularPrice | 1 | 2.00 | 1 |
videostore.RegularPrice | 2 | 2.00 | 1 |
videostore.RegularPrice | 3 | 3.50 | 1 |
videostore.RegularPrice | 4 | 5.00 | 1 |
videostore.RegularPrice | 5 | 6.50 | 1 |
videostore.NewReleasePrice | 1 | 3.00 | 1 |
videostore.NewReleasePrice | 2 | 6.00 | 2 |
videostore.NewReleasePrice | 3 | 9.00 | 2 |
videostore.ChildrensMoviePrice | 1 | 1.50 | 1 |
videostore.ChildrensMoviePrice | 2 | 1.50 | 1 |
videostore.ChildrensMoviePrice | 3 | 1.50 | 1 |
videostore.ChildrensMoviePrice | 4 | 3.00 | 1 |
videostore.ChildrensMoviePrice | 5 | 4.50 | 1 |
videostore.ChildrensMoviePrice | 6 | 6.00 | 1 |
Here, we're testing a function which obviously was not designed to be tested in small grains.
One drawback is that we have to inject some state into the system,
before we get interested in any test results.
The intermediary steps could be tested as well, but our customers are only interested in the correct statement.
The dontCare
column is really only a flag to make that distinction explicit.
Note: I'm not sure whether I'd expect to unformat the String
value here
(being the reason why the test fails).
videostore.CustomerStatement | ||||
movieName | movieCategory | daysRented | dontCare | statement() |
The Jungle Book | videostore.ChildrensMoviePrice | 2 | true | error |
Brazil | videostore.RegularPrice | 4 | true | error |
Crouching Tiger Hidden Dragon | videostore.NewReleasePrice | 1 | false | Rental Record for Quentin Tarantino\n\tThe Jungle Book\t1.5\n\tBrazil\t5.0\n\tCrouching Tiger Hidden Dragon\t3.0\nAmount owed is 9.5\nYou earned 3.0 frequent renter points |
Here is an interesting case:
The check of frequentRenterPoints()
claims to be both 1
and 2
,
but only if defined of type integer
.
videostore.Pricing | |||
movieCategory | daysRented | charge() | frequentRenterPoints() |
videostore.ChildrensMoviePrice | 2 | 1.50 | 2 |
videostore.ChildrensMoviePrice | 2 | 1.50 | 1 |
videostore.ChildrensMoviePrice | 2 | 1.50 | 2.0 |
videostore.ChildrensMoviePrice | 2 | 1.50 | 1.0 |