Code Examples for Working Effectively with Unit Tests
public class CustomerTest {
Customer john, steve, pat, david;
String johnName = "John",
steveName = "Steve",
patName = "Pat",
davidName = "David";
Customer[] customers;
@Before
public void setup() {
david = ObjectMother
.customerWithNoRentals(
davidName);
john = ObjectMother
.customerWithOneNewRelease(
johnName);
pat = ObjectMother
.customerWithOneOfEachRentalType(
patName);
steve = ObjectMother
.customerWithOneNewReleaseAndOneRegular(
steveName);
customers =
new Customer[]
{ david, john, steve, pat};
}
@Test
public void getName() {
assertEquals(
davidName, david.getName());
assertEquals(
johnName, john.getName());
assertEquals(
steveName, steve.getName());
assertEquals(
patName, pat.getName());
}
@Test
public void statement() {
for (int i=0; i<customers.length; i++) {
assertEquals(
expStatement(
"Rental record for %s\n" +
"%sAmount owed is %s\n" +
"You earned %s frequent " +
"renter points",
customers[i],
rentalInfo(
"\t", "",
customers[i].getRentals())),
customers[i].statement());
}
}
@Test
public void htmlStatement() {
for (int i=0; i<customers.length; i++) {
assertEquals(
expStatement(
"<h1>Rental record for " +
"<em>%s</em></h1>\n%s" +
"<p>Amount owed is <em>%s</em>" +
"</p>\n<p>You earned <em>%s" +
" frequent renter points</em></p>",
customers[i],
rentalInfo(
"<p>", "</p>",
customers[i].getRentals())),
customers[i].htmlStatement());
}
}
@Test
(expected=IllegalArgumentException.class)
public void invalidTitle() {
ObjectMother
.customerWithNoRentals("Bob")
.addRental(
new Rental(
new Movie("Crazy, Stupid, Love.",
Movie.Type.UNKNOWN),
4));
}
public static String rentalInfo(
String startsWith,
String endsWith,
List<Rental> rentals) {
String result = "";
for (Rental rental : rentals)
result += String.format(
"%s%s\t%s%s\n",
startsWith,
rental.getMovie().getTitle(),
rental.getCharge(),
endsWith);
return result;
}
public static String expStatement(
String formatStr,
Customer customer,
String rentalInfo) {
return String.format(
formatStr,
customer.getName(),
rentalInfo,
customer.getTotalCharge(),
customer.getTotalPoints());
}
}
public class ObjectMother {
public static Customer
customerWithOneOfEachRentalType(
String name) {
Customer result =
customerWithOneNewReleaseAndOneRegular(
name);
result.addRental(
new Rental(
new Movie("Lion King", CHILDREN), 3));
return result;
}
public static Customer
customerWithOneNewReleaseAndOneRegular(
String n) {
Customer result =
customerWithOneNewRelease(n);
result.addRental(
new Rental(
new Movie("Scarface", REGULAR), 3));
return result;
}
public static Customer
customerWithOneNewRelease(
String name) {
Customer result =
customerWithNoRentals(name);
result.addRental(
new Rental(
new Movie(
"Godfather 4", NEW_RELEASE), 3));
return result;
}
public static Customer
customerWithNoRentals(String name) {
return new Customer(name);
}
}
public class Customer {
private String name;
private List<Rental> rentals =
new ArrayList<Rental>();
public Customer(String name) {
this.name = name;
}
public String getName() {
return name;
}
public List<Rental> getRentals() {
return rentals;
}
public void addRental(Rental rental) {
rentals.add(rental);
}
public String statement() {
String result =
"Rental record for " + getName() + "\n";
for (Rental rental : rentals)
result +=
"\t" + rental.getLineItem() + "\n";
result +=
"Amount owed is " + getTotalCharge() +
"\n" + "You earned " +
getTotalPoints() +
" frequent renter points";
return result;
}
public String htmlStatement() {
String result =
"<h1>Rental record for <em>" +
getName() + "</em></h1>\n";
for (Rental rental : rentals)
result += "<p>" + rental.getLineItem() +
"</p>\n";
result +=
"<p>Amount owed is <em>" +
getTotalCharge() + "</em></p>\n" +
"<p>You earned <em>" +
getTotalPoints() +
" frequent renter points</em></p>";
return result;
}
public double getTotalCharge() {
double total = 0;
for (Rental rental : rentals)
total += rental.getCharge();
return total;
}
public int getTotalPoints() {
int total = 0;
for (Rental rental : rentals)
total += rental.getPoints();
return total;
}
}
public class Rental {
Movie movie;
private int daysRented;
public Rental(Movie movie, int daysRented) {
this.movie = movie;
this.daysRented = daysRented;
}
public Movie getMovie() {
return movie;
}
public int getDaysRented() {
return daysRented;
}
public double getCharge() {
return movie.getCharge(daysRented);
}
public int getPoints() {
return movie.getPoints(daysRented);
}
public String getLineItem() {
return
movie.getTitle() + " " + getCharge();
}
}
public class Movie {
public enum Type {
REGULAR, NEW_RELEASE, CHILDREN, UNKNOWN;
}
private String title;
Price price;
public Movie(
String title, Movie.Type priceCode) {
this.title = title;
setPriceCode(priceCode);
}
public String getTitle() {
return title;
}
private void setPriceCode(
Movie.Type priceCode) {
switch (priceCode) {
case CHILDREN:
price = new ChildrensPrice();
break;
case NEW_RELEASE:
price = new NewReleasePrice();
break;
case REGULAR:
price = new RegularPrice();
break;
default:
throw new IllegalArgumentException(
"invalid price code");
}
}
public double getCharge(int daysRented) {
return price.getCharge(daysRented);
}
public int getPoints(int daysRented) {
return price.getPoints(daysRented);
}
}
public abstract class Price {
abstract double getCharge(int daysRented);
int getPoints(int daysRented) {
return 1;
}
}
public class ChildrensPrice extends Price {
@Override
double getCharge(int daysRented) {
double amount = 1.5;
if (daysRented > 3)
amount += (daysRented - 3) * 1.5;
return amount;
}
}
public class RegularPrice extends Price {
@Override
public double getCharge(int daysRented) {
double amount = 2;
if (daysRented > 2)
amount += (daysRented - 2) * 1.5;
return amount;
}
}
public class NewReleasePrice extends Price {
@Override
public double getCharge(int daysRented) {
return daysRented * 3;
}
@Override
int getPoints(int daysRented) {
if (daysRented > 1)
return 2;
return 1;
}
}
public class CustomerTest {
Customer john, steve, pat, david;
String johnName = "John",
steveName = "Steve",
patName = "Pat",
davidName = "David";
Customer[] customers;
@Before
public void setup() {
david = ObjectMother
.customerWithNoRentals(davidName);
john = ObjectMother
.customerWithOneNewRelease(johnName);
pat = ObjectMother
.customerWithOneOfEachRentalType(
patName);
steve = ObjectMother
.customerWithOneNewReleaseAndOneRegular(
steveName);
customers = new Customer[] {
david, john, steve, pat };
}
@Test
public void davidStatement() {
assertEquals(
expStatement(
"Rental record for %s\n%sAmount " +
"owed is %s\nYou earned %s " +
"frequent renter points",
david,
rentalInfo(
"\t", "", david.getRentals())),
david.statement());
}
@Test
public void johnStatement() {
assertEquals(
expStatement(
"Rental record for %s\n%sAmount " +
"owed is %s\nYou earned %s " +
"frequent renter points",
john,
rentalInfo(
"\t", "", john.getRentals())),
john.statement());
}
@Test
public void patStatement() {
assertEquals(
expStatement(
"Rental record for %s\n%sAmount " +
"owed is %s\nYou earned %s " +
"frequent renter points",
pat,
rentalInfo(
"\t", "", pat.getRentals())),
pat.statement());
}
@Test
public void steveStatement() {
assertEquals(
expStatement(
"Rental record for %s\n%s" +
"Amount owed is %s\nYou earned %s " +
"frequent renter points",
steve,
rentalInfo(
"\t", "", steve.getRentals())),
steve.statement());
}
public static String rentalInfo(
String startsWith,
String endsWith,
List<Rental> rentals) {
String result = "";
for (Rental rental : rentals)
result += String.format(
"%s%s\t%s%s\n",
startsWith,
rental.getMovie().getTitle(),
rental.getCharge(),
endsWith);
return result;
}
public static String expStatement(
String formatStr,
Customer customer,
String rentalInfo) {
return String.format(
formatStr,
customer.getName(),
rentalInfo,
customer.getTotalCharge(),
customer.getTotalPoints());
}
}
public class CustomerTest {
Customer john, steve, pat, david;
String johnName = "John",
steveName = "Steve",
patName = "Pat",
davidName = "David";
Customer[] customers;
@Before
public void setup() {
david = ObjectMother
.customerWithNoRentals(davidName);
john = ObjectMother
.customerWithOneNewRelease(johnName);
pat = ObjectMother
.customerWithOneOfEachRentalType(
patName);
steve = ObjectMother
.customerWithOneNewReleaseAndOneRegular(
steveName);
customers = new Customer[] {
david, john, steve, pat };
}
@Test
public void davidStatement() {
assertEquals(
"Rental record for David\nAmount " +
"owed is 0.0\n" +
"You earned 0 frequent renter points",
david.statement());
}
@Test
public void johnStatement() {
assertEquals(
"Rental record for John\n\t" +
"Godfather 4\t9.0\n" +
"Amount owed is 9.0\n" +
"You earned 2 frequent renter points",
john.statement());
}
@Test
public void patStatement() {
assertEquals(
"Rental record for Pat\n\t" +
"Godfather 4\t9.0\n" +
"\tScarface\t3.5\n" +
"\tLion King\t1.5\n" +
"Amount owed is 14.0\n" +
"You earned 4 frequent renter points",
pat.statement());
}
@Test
public void steveStatement() {
assertEquals(
"Rental record for Steve\n\t" +
"Godfather 4\t9.0\n" +
"\tScarface\t3.5\n" +
"Amount owed is 12.5\n" +
"You earned 3 frequent renter points",
steve.statement());
}
}
public class CustomerTest {
@Test
public void noRentalsStatement() {
assertEquals(
"Rental record for David\nAmount " +
"owed is 0.0\n" +
"You earned 0 frequent renter points",
ObjectMother
.customerWithNoRentals(
"David").statement());
}
@Test
public void oneNewReleaseStatement() {
assertEquals(
"Rental record for John\n\t" +
"Godfather 4 9.0\n" +
"Amount owed is 9.0\n" +
"You earned 2 frequent renter points",
ObjectMother
.customerWithOneNewRelease(
"John").statement());
}
@Test
public void allRentalTypesStatement() {
assertEquals(
"Rental record for Pat\n\t" +
"Godfather 4 9.0\n" +
"\tScarface 3.5\n\tLion King 1.5\n" +
"Amount owed is 14.0\n" +
"You earned 4 frequent renter points",
ObjectMother
.customerWithOneOfEachRentalType(
"Pat").statement());
}
@Test
public void
newReleaseAndRegularStatement() {
assertEquals(
"Rental record for Steve\n\t" +
"Godfather 4 9.0\n" +
"\tScarface 3.5\n" +
"Amount owed is 12.5\n" +
"You earned 3 frequent renter points",
ObjectMother
.customerWithOneNewReleaseAndOneRegular(
"Steve").statement());
}
}
public class a {
public static CustomerBuilder customer =
new CustomerBuilder();
public static RentalBuilder rental =
new RentalBuilder();
public static MovieBuilder movie =
new MovieBuilder();
public static class CustomerBuilder {
Rental[] rentals;
String name;
CustomerBuilder() {
this("Jim", new Rental[0]);
}
CustomerBuilder(
String name, Rental[] rentals) {
this.name = name;
this.rentals = rentals;
}
public CustomerBuilder w(
RentalBuilder... builders) {
Rental[] rentals =
new Rental[builders.length];
for (int i=0; i<builders.length; i++) {
rentals[i] = builders[i].build();
}
return
new CustomerBuilder(name, rentals);
}
public CustomerBuilder w(String name) {
return
new CustomerBuilder(name, rentals);
}
public Customer build() {
Customer result = new Customer(name);
for (Rental rental : rentals) {
result.addRental(rental);
}
return result;
}
}
public static class RentalBuilder {
final Movie movie;
final int days;
RentalBuilder() {
this(new MovieBuilder().build(), 3);
}
RentalBuilder(Movie movie, int days) {
this.movie = movie;
this.days = days;
}
public RentalBuilder w(
MovieBuilder movie) {
return
new RentalBuilder(
movie.build(), days);
}
public Rental build() {
return new Rental(movie, days);
}
}
public static class MovieBuilder {
final String name;
final Movie.Type type;
MovieBuilder() {
this("Godfather 4",
Movie.Type.NEW_RELEASE);
}
MovieBuilder(
String name, Movie.Type type) {
this.name = name;
this.type = type;
}
public MovieBuilder w(Movie.Type type) {
return new MovieBuilder(name, type);
}
public MovieBuilder w(String name) {
return new MovieBuilder(name, type);
}
public Movie build() {
return new Movie(name, type);
}
}
}
public class CustomerTest {
@Test
public void noRentalsStatement() {
assertEquals(
"Rental record for David\nAmount " +
"owed is 0.0\nYou earned 0 frequent " +
"renter points",
a.customer.w(
"David").build().statement());
}
@Test
public void oneNewReleaseStatement() {
assertEquals(
"Rental record for John\n\t" +
"Godfather 4 9.0\nAmount owed is " +
"9.0\nYou earned 2 frequent renter " +
"points",
a.customer.w("John").w(
a.rental.w(
a.movie.w(NEW_RELEASE))).build()
.statement());
}
@Test
public void allRentalTypesStatement() {
assertEquals(
"Rental record for Pat\n\t" +
"Godfather 4 9.0\n\tScarface 3.5\n" +
"\tLion King 1.5\nAmount owed is " +
"14.0\nYou earned 4 frequent renter " +
"points",
a.customer.w("Pat").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(a.movie.w("Scarface").w(
REGULAR)),
a.rental.w(a.movie.w("Lion King").w(
CHILDREN))).build()
.statement());
}
@Test
public void
newReleaseAndRegularStatement() {
assertEquals(
"Rental record for Steve\n\t" +
"Godfather 4 9.0\n\tScarface 3.5\n" +
"Amount owed is 12.5\nYou earned 3 " +
"frequent renter points",
a.customer.w("Steve").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(
a.movie.w(
"Scarface").w(REGULAR))).build()
.statement());
}
}
public class CustomerTest {
Customer john, steve, pat, david;
String johnName = "John",
steveName = "Steve",
patName = "Pat",
davidName = "David";
Customer[] customers;
@Before
public void setup() {
david = ObjectMother
.customerWithNoRentals(
davidName);
john = ObjectMother
.customerWithOneNewRelease(
johnName);
pat = ObjectMother
.customerWithOneOfEachRentalType(
patName);
steve = ObjectMother
.customerWithOneNewReleaseAndOneRegular(
steveName);
customers =
new Customer[]
{ david, john, steve, pat};
}
@Test
public void getName() {
assertEquals(
davidName, david.getName());
assertEquals(
johnName, john.getName());
assertEquals(
steveName, steve.getName());
assertEquals(
patName, pat.getName());
}
@Test
public void statement() {
for (int i=0; i<customers.length; i++) {
assertEquals(
expStatement(
"Rental record for %s\n" +
"%sAmount owed is %s\n" +
"You earned %s frequent " +
"renter points",
customers[i],
rentalInfo(
"\t", "",
customers[i].getRentals())),
customers[i].statement());
}
}
@Test
public void htmlStatement() {
for (int i=0; i<customers.length; i++) {
assertEquals(
expStatement(
"<h1>Rental record for " +
"<em>%s</em></h1>\n%s" +
"<p>Amount owed is <em>%s</em>" +
"</p>\n<p>You earned <em>%s" +
" frequent renter points</em></p>",
customers[i],
rentalInfo(
"<p>", "</p>",
customers[i].getRentals())),
customers[i].htmlStatement());
}
}
@Test
(expected=IllegalArgumentException.class)
public void invalidTitle() {
ObjectMother
.customerWithNoRentals("Bob")
.addRental(
new Rental(
new Movie("Crazy, Stupid, Love.",
Movie.Type.UNKNOWN),
4));
}
public static String rentalInfo(
String startsWith,
String endsWith,
List<Rental> rentals) {
String result = "";
for (Rental rental : rentals)
result += String.format(
"%s%s\t%s%s\n",
startsWith,
rental.getMovie().getTitle(),
rental.getCharge(),
endsWith);
return result;
}
public static String expStatement(
String formatStr,
Customer customer,
String rentalInfo) {
return String.format(
formatStr,
customer.getName(),
rentalInfo,
customer.getTotalCharge(),
customer.getTotalPoints());
}
}
public class CustomerTest {
@Test
public void getName() {
assertEquals(
"John",
a.customer.w(
"John").build().getName());
}
@Test
public void noRentalsStatement() {
assertEquals(
"Rental record for David\nAmount " +
"owed is 0.0\nYou earned 0 frequent " +
"renter points",
a.customer.w(
"David").build().statement());
}
@Test
public void oneNewReleaseStatement() {
assertEquals(
"Rental record for John\n" +
"\tGodfather 4 9.0\n" +
"Amount owed is 9.0\n" +
"You earned 2 frequent renter points",
a.customer.w("John").w(
a.rental.w(
a.movie.w(
NEW_RELEASE))).build()
.statement());
}
@Test
public void allRentalTypesStatement() {
assertEquals(
"Rental record for Pat\n" +
"\tGodfather 4 9.0\n" +
"\tScarface 3.5\n" +
"\tLion King 1.5\n" +
"Amount owed is 14.0\n" +
"You earned 4 frequent renter points",
a.customer.w("Pat").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(
a.movie.w("Scarface").w(REGULAR)),
a.rental.w(
a.movie.w("Lion King").w(
CHILDREN))).build().statement());
}
@Test
public void
newReleaseAndRegularStatement() {
assertEquals(
"Rental record for Steve\n" +
"\tGodfather 4 9.0\n" +
"\tScarface 3.5\n" +
"Amount owed is 12.5\n" +
"You earned 3 frequent renter points",
a.customer.w("Steve").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(
a.movie.w("Scarface").w(
REGULAR))).build().statement());
}
@Test
public void noRentalsHtmlStatement() {
assertEquals(
"<h1>Rental record for <em>David" +
"</em></h1>\n<p>Amount owed is <em>" +
"0.0</em></p>\n<p>You earned <em>0 " +
"frequent renter points</em></p>",
a.customer.w(
"David").build().htmlStatement());
}
@Test
public void oneNewReleaseHtmlStatement() {
assertEquals(
"<h1>Rental record for <em>John</em>" +
"</h1>\n<p>Godfather 4 9.0</p>\n" +
"<p>Amount owed is <em>9.0</em></p>" +
"\n<p>You earned <em>2 frequent " +
"renter points</em></p>",
a.customer.w("John").w(
a.rental.w(
a.movie.w(
NEW_RELEASE))).build()
.htmlStatement());
}
@Test
public void allRentalTypesHtmlStatement() {
assertEquals(
"<h1>Rental record for <em>Pat</em>" +
"</h1>\n<p>Godfather 4 9.0</p>\n" +
"<p>Scarface 3.5</p>\n<p>Lion King" +
" 1.5</p>\n<p>Amount owed is <em>" +
"14.0</em></p>\n<p>You earned <em>" +
"4 frequent renter points</em></p>",
a.customer.w("Pat").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(
a.movie.w("Scarface").w(REGULAR)),
a.rental.w(
a.movie.w("Lion King").w(
CHILDREN))).build()
.htmlStatement());
}
@Test
public void
newReleaseAndRegularHtmlStatement() {
assertEquals(
"<h1>Rental record for <em>Steve" +
"</em></h1>\n<p>Godfather 4 9.0</p>" +
"\n<p>Scarface 3.5</p>\n<p>Amount " +
"owed is <em>12.5</em></p>\n<p>" +
"You earned <em>3 frequent renter " +
"points</em></p>",
a.customer.w("Steve").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(
a.movie.w("Scarface").w(
REGULAR))).build()
.htmlStatement());
}
@Test
(expected=IllegalArgumentException.class)
public void invalidTitle() {
a.customer.w(
a.rental.w(
a.movie.w(UNKNOWN))).build();
}
}
public class RentalTest {
@Test
public void rentalIsStartedIfInStore() {
Movie movie = a.movie.build();
Rental rental =
a.rental.w(movie).build();
Store store = a.store.w(movie).build();
rental.start(store);
assertTrue(rental.isStarted());
assertEquals(
0, store.getAvailability(movie));
}
@Test
public void
rentalDoesNotStartIfNotAvailable() {
Movie movie = a.movie.build();
Rental rental = a.rental.build();
Store store = a.store.build();
rental.start(store);
assertFalse(rental.isStarted());
assertEquals(
0, store.getAvailability(movie));
}
}
public class RentalTest {
@Test
public void rentalIsStartedIfInStore() {
Movie movie = a.movie.build();
Rental rental =
a.rental.w(movie).build();
Store store = mock(Store.class);
when(store.getAvailability(movie))
.thenReturn(1);
rental.start(store);
assertTrue(rental.isStarted());
verify(store).remove(movie);
}
@Test
public void
rentalDoesNotStartIfNotAvailable() {
Rental rental = a.rental.build();
Store store = mock(Store.class);
rental.start(store);
assertFalse(rental.isStarted());
verify(
store, never()).remove(
any(Movie.class));
}
}
public class CustomerTest {
@Test
public void getName() {
assertEquals(
"John",
a.customer.w(
"John").build().getName());
}
@Test
public void noRentalsStatement() {
assertEquals(
"Rental record for David\nAmount" +
" owed is 0.0\n" +
"You earned 0 frequent renter points",
a.customer.w(
"David").build().statement());
}
@Test
public void oneNewReleaseStatement() {
assertEquals(
"Rental record for John\n" +
"\tGodfather 4 9.0\n" +
"Amount owed is 9.0\n" +
"You earned 2 frequent renter points",
a.customer.w("John").w(
a.rental.w(
a.movie.w(
NEW_RELEASE))).build()
.statement());
}
@Test
public void allRentalTypesStatement() {
assertEquals(
"Rental record for Pat\n" +
"\tGodfather 4 9.0\n" +
"\tScarface 3.5\n" +
"\tLion King 1.5\n" +
"Amount owed is 14.0\n" +
"You earned 4 frequent renter points",
a.customer.w("Pat").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(
a.movie.w("Scarface").w(REGULAR)),
a.rental.w(
a.movie.w(
"Lion King").w(
CHILDREN))).build()
.statement());
}
@Test
public void
newReleaseAndRegularStatement() {
assertEquals(
"Rental record for Steve\n" +
"\tGodfather 4 9.0\n" +
"\tScarface 3.5\n" +
"Amount owed is 12.5\n" +
"You earned 3 frequent renter points",
a.customer.w("Steve").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(
a.movie.w("Scarface").w(
REGULAR))).build()
.statement());
}
@Test
public void noRentalsHtmlStatement() {
assertEquals(
"<h1>Rental record for <em>David" +
"</em></h1>\n<p>Amount owed is " +
"<em>0.0</em></p>\n<p>" +
"You earned <em>0 frequent renter " +
"points</em></p>",
a.customer.w(
"David").build().htmlStatement());
}
@Test
public void oneNewReleaseHtmlStatement() {
assertEquals(
"<h1>Rental record for <em>John</em>" +
"</h1>\n<p>Godfather 4 9.0</p>\n" +
"<p>Amount owed is <em>9.0</em></p>" +
"\n<p>You earned <em>2 frequent " +
"renter points</em></p>",
a.customer.w("John").w(
a.rental.w(
a.movie.w(NEW_RELEASE))).build()
.htmlStatement());
}
@Test
public void allRentalTypesHtmlStatement() {
assertEquals(
"<h1>Rental record for <em>Pat</em>" +
"</h1>\n<p>Godfather 4 9.0</p>\n<p>" +
"Scarface 3.5</p>\n<p>Lion King 1.5" +
"</p>\n<p>Amount owed is <em>14.0" +
"</em></p>\n<p>You earned <em>4 " +
"frequent renter points</em></p>",
a.customer.w("Pat").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(a.movie.w("Scarface").w(
REGULAR)),
a.rental.w(a.movie.w("Lion King").w(
CHILDREN))).build()
.htmlStatement());
}
@Test
public void
newReleaseAndRegularHtmlStatement() {
assertEquals(
"<h1>Rental record for <em>Steve" +
"</em></h1>\n<p>Godfather 4 9.0</p>" +
"\n<p>Scarface 3.5</p>\n<p>Amount " +
"owed is <em>12.5</em></p>\n<p>You " +
"earned <em>3 frequent renter points" +
"</em></p>",
a.customer.w("Steve").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(a.movie.w("Scarface").w(
REGULAR))).build()
.htmlStatement());
}
@Test
(expected=IllegalArgumentException.class)
public void invalidTitle() {
a.customer.w(
a.rental.w(
a.movie.w(UNKNOWN))).build();
}
}
public class MovieTest {
@Test
(expected=IllegalArgumentException.class)
public void invalidTitle() {
a.movie.w(UNKNOWN).build();
}
}
public class CustomerTest {
@Test
public void noRentalsStatement() {
assertEquals(
"Rental record for Jim\nAmount owed" +
" is 0.0\n" +
"You earned 0 frequent renter points",
a.customer.build().statement());
}
@Test
public void oneRentalStatement() {
assertEquals(
"Rental record for Jim\n\tnull\n" +
"Amount owed is 0.0\n" +
"You earned 0 frequent renter points",
a.customer.w(
mock(Rental.class)).build()
.statement());
}
@Test
public void twoRentalsStatement() {
assertEquals(
"Rental record for Jim\n\t" +
"null\n\tnull\n" +
"Amount owed is 0.0\n" +
"You earned 0 frequent renter points",
a.customer.w(
mock(Rental.class),
mock(Rental.class)).build()
.statement());
}
}
public class CustomerTest {
@Test
public void noRentalsCharge() {
assertEquals(
0.0,
a.customer.build().getTotalCharge(),
0);
}
@Test
public void twoRentalsCharge() {
Rental rental = mock(Rental.class);
when(rental.getCharge()).thenReturn(2.0);
assertEquals(
4.0,
a.customer.w(
rental,
rental).build().getTotalCharge(),
0);
}
@Test
public void threeRentalsCharge() {
Rental rental = mock(Rental.class);
when(rental.getCharge()).thenReturn(2.0);
assertEquals(
6.0,
a.customer.w(
rental,
rental,
rental).build().getTotalCharge(),
0);
}
@Test
public void noRentalsPoints() {
assertEquals(
0,
a.customer.build().getTotalPoints());
}
@Test
public void twoRentalsPoints() {
Rental rental = mock(Rental.class);
when(rental.getPoints()).thenReturn(2);
assertEquals(
4,
a.customer.w(
rental,
rental).build().getTotalPoints());
}
@Test
public void threeRentalsPoints() {
Rental rental = mock(Rental.class);
when(rental.getPoints()).thenReturn(2);
assertEquals(
6,
a.customer.w(
rental,
rental,
rental).build().getTotalPoints());
}
}
public class MovieTest {
@Test
public void getChargeForChildrens() {
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(1),
0);
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(2),
0);
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(3),
0);
assertEquals(
3.0,
a.movie.w(
CHILDREN).build().getCharge(4),
0);
assertEquals(
4.5,
a.movie.w(
CHILDREN).build().getCharge(5),
0);
}
@Test
public void getChargeForNewRelease() {
assertEquals(
3.0,
a.movie.w(
NEW_RELEASE).build().getCharge(1),
0);
assertEquals(
6.0,
a.movie.w(
NEW_RELEASE).build().getCharge(2),
0);
assertEquals(
9.0,
a.movie.w(
NEW_RELEASE).build().getCharge(3),
0);
}
@Test
public void getChargeForRegular() {
assertEquals(
2.0,
a.movie.w(
REGULAR).build().getCharge(1),
0);
assertEquals(
2.0,
a.movie.w(
REGULAR).build().getCharge(2),
0);
assertEquals(
3.5,
a.movie.w(
REGULAR).build().getCharge(3),
0);
assertEquals(
5.0,
a.movie.w(
REGULAR).build().getCharge(4),
0);
}
@Test
public void getPointsForChildrens() {
assertEquals(
1,
a.movie.w(
CHILDREN).build().getPoints(1));
assertEquals(
1,
a.movie.w(
CHILDREN).build().getPoints(2));
}
@Test
public void getPointsForNewRelease() {
assertEquals(
1,
a.movie.w(
NEW_RELEASE).build().getPoints(1));
assertEquals(
2,
a.movie.w(
NEW_RELEASE).build().getPoints(2));
assertEquals(
2,
a.movie.w(
NEW_RELEASE).build().getPoints(3));
}
@Test
public void getPointsForRegular() {
assertEquals(
1,
a.movie.w(
REGULAR).build().getPoints(1));
assertEquals(
1,
a.movie.w(
REGULAR).build().getPoints(2));
}
}
public class CustomerTest {
@Test
public void allRentalTypesStatement() {
assertEquals(
"Rental record for Pat\n" +
"\tGodfather 4 9.0\n" +
"\tScarface 3.5\n" +
"\tLion King 1.5\n" +
"Amount owed is 14.0\n" +
"You earned 4 frequent renter points",
a.customer.w("Pat").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(a.movie.w("Scarface").w(
REGULAR)),
a.rental.w(a.movie.w("Lion King").w(
CHILDREN)))
.build().statement());
}
@Test
public void allRentalTypesHtmlStatement() {
assertEquals(
"<h1>Rental record for " +
"<em>Pat</em></h1>\n" +
"<p>Godfather 4 9.0</p>\n" +
"<p>Scarface 3.5</p>\n" +
"<p>Lion King 1.5</p>\n" +
"<p>Amount owed is " +
"<em>14.0</em></p>\n<p>" +
"You earned <em>4 frequent " +
"renter points</em></p>",
a.customer.w("Pat").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(a.movie.w("Scarface").w(
REGULAR)),
a.rental.w(a.movie.w("Lion King").w(
CHILDREN)))
.build().htmlStatement());
}
}
public class CustomerTest {
@Test
public void getName() {
assertEquals(
"John",
a.customer.w(
"John").build().getName());
}
@Test
public void noRentalsStatement() {
assertEquals(
"Rental record for Jim\nAmount owed" +
" is 0.0\nYou earned 0 frequent " +
"renter points",
a.customer.build().statement());
}
@Test
public void oneRentalStatement() {
assertEquals(
"Rental record for Jim\n\tnull\n" +
"Amount owed is 0.0\n" +
"You earned 0 frequent renter points",
a.customer.w(
mock(Rental.class)).build()
.statement());
}
@Test
public void twoRentalsStatement() {
assertEquals(
"Rental record for Jim\n\tnull\n" +
"\tnull\nAmount owed is 0.0\n" +
"You earned 0 frequent renter points",
a.customer.w(
mock(Rental.class),
mock(Rental.class)).build()
.statement());
}
@Test
public void noRentalsHtmlStatement() {
assertEquals(
"<h1>Rental record for <em>Jim</em>" +
"</h1>\n<p>Amount owed is <em>0.0" +
"</em></p>\n<p>You earned <em>0 " +
"frequent renter points</em></p>",
a.customer.build().htmlStatement());
}
@Test
public void oneRentalHtmlStatement() {
Rental rental = mock(Rental.class);
assertEquals(
"<h1>Rental record for <em>Jim</em>" +
"</h1>\n<p>null</p>\n<p>Amount owed " +
"is <em>0.0</em></p>\n<p>You earned " +
"<em>0 frequent renter points</em>" +
"</p>",
a.customer.w(
mock(Rental.class)).build()
.htmlStatement());
}
@Test
public void twoRentalsHtmlStatement() {
assertEquals(
"<h1>Rental record for <em>Jim</em>" +
"</h1>\n<p>null</p>\n<p>null</p>\n" +
"<p>Amount owed is <em>0.0</em></p>" +
"\n<p>You earned <em>0 frequent" +
" renter points</em></p>",
a.customer.w(
mock(Rental.class),
mock(Rental.class)).build()
.htmlStatement());
}
@Test
public void noRentalsCharge() {
assertEquals(
0.0,
a.customer.build().getTotalCharge(),
0);
}
@Test
public void twoRentalsCharge() {
Rental rental = mock(Rental.class);
when(rental.getCharge()).thenReturn(2.0);
assertEquals(
6.0,
a.customer.w(
rental,
rental).build().getTotalCharge(),
0);
}
@Test
public void threeRentalsCharge() {
Rental rental = mock(Rental.class);
when(rental.getCharge()).thenReturn(2.0);
assertEquals(
6.0,
a.customer.w(
rental,
rental,
rental).build().getTotalCharge(),
0);
}
@Test
public void noRentalsPoints() {
assertEquals(
0,
a.customer.build().getTotalPoints());
}
@Test
public void twoRentalsPoints() {
Rental rental = mock(Rental.class);
when(rental.getPoints()).thenReturn(2);
assertEquals(
4,
a.customer.w(
rental,
rental).build().getTotalPoints());
}
@Test
public void threeRentalsPoints() {
Rental rental = mock(Rental.class);
when(rental.getPoints()).thenReturn(2);
assertEquals(
6,
a.customer.w(
rental,
rental,
rental).build().getTotalPoints());
}
}
public class CustomerTest {
@Test
public void allRentalTypesStatement() {
assertEquals(
"Rental record for Pat\n" +
"\tGodfather 4 9.0\n" +
"\tScarface 3.5\n" +
"\tLion King 1.5\n" +
"Amount owed is 14.0\n" +
"You earned 4 frequent renter points",
a.customer.w("Pat").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(a.movie.w("Scarface").w(
REGULAR)),
a.rental.w(a.movie.w("Lion King").w(
CHILDREN)))
.build().statement());
}
@Test
public void allRentalTypesHtmlStatement() {
assertEquals(
"<h1>Rental record for <em>Pat" +
"</em></h1>\n" +
"<p>Godfather 4 9.0</p>\n" +
"<p>Scarface 3.5</p>\n" +
"<p>Lion King 1.5</p>\n" +
"<p>Amount owed is " +
"<em>14.0</em></p>\n<p>" +
"You earned <em>4 " +
"frequent renter points</em></p>",
a.customer.w("Pat").w(
a.rental.w(a.movie.w(NEW_RELEASE)),
a.rental.w(a.movie.w("Scarface").w(
REGULAR)),
a.rental.w(a.movie.w("Lion King").w(
CHILDREN)))
.build().htmlStatement());
}
}
public class Customer {
private String name;
private List<Rental> rentals
= new ArrayList<Rental>();
public Customer(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void addRental(Rental rental) {
rentals.add(rental);
}
public String statement() {
String result =
"Rental record for " +
getName() + "\n";
for (Rental rental : rentals)
result +=
"\t" + rental.getLineItem() + "\n";
result += "Amount owed is " +
getTotalCharge() + "\n" +
"You earned " + getTotalPoints() +
" frequent renter points";
return result;
}
public String htmlStatement() {
String result =
"<h1>Rental record for <em>" +
getName() + "</em></h1>\n";
for (Rental rental : rentals)
result +=
"<p>" + rental.getLineItem() +
"</p>\n";
result +=
"<p>Amount owed is <em>" +
getTotalCharge() + "</em></p>\n" +
"<p>You earned <em>" +
getTotalPoints() +
" frequent renter points</em></p>";
return result;
}
public double getTotalCharge() {
double total = 0;
for (Rental rental : rentals)
total += rental.getCharge();
return total;
}
public int getTotalPoints() {
int total = 0;
for (Rental rental : rentals)
total += rental.getPoints();
return total;
}
}
public class MovieTest {
@Test
public void getChargeForChildrens() {
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(1),
0);
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(2),
0);
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(3),
0);
assertEquals(
3.0,
a.movie.w(
CHILDREN).build().getCharge(4),
0);
assertEquals(
4.5,
a.movie.w(
CHILDREN).build().getCharge(5),
0);
}
@Test
public void getChargeForNewRelease() {
assertEquals(
3.0,
a.movie.w(
NEW_RELEASE).build().getCharge(1),
0);
assertEquals(
6.0,
a.movie.w(
NEW_RELEASE).build().getCharge(2),
0);
assertEquals(
9.0,
a.movie.w(
NEW_RELEASE).build().getCharge(3),
0);
}
@Test
public void getChargeForRegular() {
assertEquals(
2.0,
a.movie.w(
REGULAR).build().getCharge(1),
0);
assertEquals(
2.0,
a.movie.w(
REGULAR).build().getCharge(2),
0);
assertEquals(
3.5,
a.movie.w(
REGULAR).build().getCharge(3),
0);
assertEquals(
5.0,
a.movie.w(
REGULAR).build().getCharge(4),
0);
}
@Test
public void getPointsForChildrens() {
assertEquals(
1,
a.movie.w(
CHILDREN).build().getPoints(1));
assertEquals(
1,
a.movie.w(
CHILDREN).build().getPoints(2));
}
@Test
public void getPointsForNewRelease() {
assertEquals(
1,
a.movie.w(
NEW_RELEASE).build().getPoints(1));
assertEquals(
2,
a.movie.w(
NEW_RELEASE).build().getPoints(2));
assertEquals(
2,
a.movie.w(
NEW_RELEASE).build().getPoints(3));
}
@Test
public void getPointsForRegular() {
assertEquals(
1,
a.movie.w(
REGULAR).build().getPoints(1));
assertEquals(
1,
a.movie.w(
REGULAR).build().getPoints(2));
}
@Test
(expected=IllegalArgumentException.class)
public void invalidTitle() {
a.movie.w(UNKNOWN).build();
}
}
public class Movie {
public enum Type {
REGULAR, NEW_RELEASE, CHILDREN, UNKNOWN;
}
private String title;
Price price;
public Movie(
String title, Movie.Type priceCode) {
this.title = title;
setPriceCode(priceCode);
}
public String getTitle() {
return title;
}
private void setPriceCode(
Movie.Type priceCode) {
switch (priceCode) {
case CHILDREN:
price = new ChildrensPrice();
break;
case NEW_RELEASE:
price = new NewReleasePrice();
break;
case REGULAR:
price = new RegularPrice();
break;
default:
throw new IllegalArgumentException(
"invalid price code");
}
}
public double getCharge(int daysRented) {
return price.getCharge(daysRented);
}
public int getPoints(int daysRented) {
return price.getPoints(daysRented);
}
}
public class RentalTest {
@Test
public void
isStartedIfInStoreStateBased() {
Movie movie = a.movie.build();
Rental rental =
a.rental.w(movie).build();
Store store = a.store.w(movie).build();
rental.start(store);
assertTrue(rental.isStarted());
assertEquals(
0, store.getAvailability(movie));
}
@Test
public void
doesNotStartIfNotAvailableStateBased() {
Movie movie = a.movie.build();
Rental rental = a.rental.build();
Store store = a.store.build();
rental.start(store);
assertFalse(rental.isStarted());
assertEquals(
0, store.getAvailability(movie));
}
@Test
public void
isStartedIfInStoreInteractionBased() {
Movie movie = a.movie.build();
Rental rental =
a.rental.w(movie).build();
Store store = mock(Store.class);
when(store.getAvailability(movie))
.thenReturn(1);
rental.start(store);
assertTrue(rental.isStarted());
verify(store).remove(movie);
}
@Test
public void
notStartedIfUnavailableInteractionBased() {
Rental rental = a.rental.build();
Store store = mock(Store.class);
rental.start(store);
assertFalse(rental.isStarted());
verify(
store, never()).remove(
any(Movie.class));
}
}
public class Rental {
Movie movie;
private int daysRented;
private boolean started;
public Rental(
Movie movie, int daysRented) {
this.movie = movie;
this.daysRented = daysRented;
}
public Movie getMovie() {
return movie;
}
public int getDaysRented() {
return daysRented;
}
public double getCharge() {
return movie.getCharge(daysRented);
}
public int getPoints() {
return movie.getPoints(daysRented);
}
public String getLineItem() {
return
movie.getTitle() + " " + getCharge();
}
public boolean isStarted() {
return started;
}
public void start(Store store) {
if (store.getAvailability(movie) > 0) {
store.remove(movie);
this.started = true;
}
}
}
public class Store {
private Map<Movie, Integer> movies;
public Store(Map<Movie, Integer> movies) {
this.movies = movies;
}
public int getAvailability(Movie movie) {
if (null == movies.get(movie))
return 0;
return movies.get(movie);
}
public boolean getAvailability(
Movie movie, int quantity) {
if (null == movies.get(movie))
return false;
return movies.get(movie) >= quantity;
}
public void remove(Movie movie) {
if (null == movies.get(movie))
return;
Integer count = movies.get(movie);
movies.put(movie, --count);
}
}
public class MovieTest {
@Test
public void getChargeForChildrens() {
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(1),
0);
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(2),
0);
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(3),
0);
assertEquals(
3.0,
a.movie.w(
CHILDREN).build().getCharge(4),
0);
assertEquals(
4.5,
a.movie.w(
CHILDREN).build().getCharge(5),
0);
}
}
public class ChildrensPrice extends Price {
@Override
public double getCharge(int daysRented) {
double amount = 1.5;
if (daysRented > 2) // *was 3*
amount += (daysRented - 2) * 1.5;
return amount;
}
}
public class MovieTest {
@Test
public void getChargeForChildrens1Day() {
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(1),
0);
}
@Test
public void getChargeForChildrens2Day() {
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(2),
0);
}
@Test
public void getChargeForChildrens3Day() {
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(3),
0);
}
@Test
public void getChargeForChildrens4Day() {
assertEquals(
3.0,
a.movie.w(
CHILDREN).build().getCharge(4),
0);
}
@Test
public void getChargeForChildrens5Day() {
assertEquals(
4.5,
a.movie.w(
CHILDREN).build().getCharge(5),
0);
}
}
public class RentalTest {
@Test
public void rentalIsStartedIfInStore() {
Movie movie = mock(Movie.class);
Rental rental =
a.rental.w(movie).build();
Store store = mock(Store.class);
when(store.getAvailability(movie))
.thenReturn(1);
rental.start(store);
assertTrue(rental.isStarted());
verify(store).remove(movie);
}
}
public class RentalTest {
@Test
public void rentalIsStartedIfInStore() {
Movie movie = mock(Movie.class);
Rental rental =
a.rental.w(movie).build();
Store store = mock(Store.class);
when(store.getAvailability(movie, 1))
.thenReturn(true);
rental.start(store);
assertTrue(rental.isStarted());
verify(store).remove(movie);
}
}
public class RentalTest {
@Test
public void rentalIsStartedIfInStore() {
Rental rental = a.rental.build();
Store store = mock(Store.class);
when(store
.getAvailability(any(Movie.class)))
.thenReturn(1);
rental.start(store);
assertTrue(rental.isStarted());
}
}
public class StoreTest {
@Test
public void storeWithNoAvailability() {
Store store = a.store.build();
assertEquals(
0,
store.getAvailability(
mock(Movie.class)));
}
@Test
public void storeWithAvailability() {
Movie movie = mock(Movie.class);
Store store =
a.store.w(movie, movie).build();
assertEquals(
2, store.getAvailability(movie));
}
@Test
public void
storeWithRemovedAvailability() {
Movie movie = mock(Movie.class);
Store store =
a.store.w(movie, movie).build();
store.remove(movie);
assertEquals(
1, store.getAvailability(movie));
}
}
public class RentalTest {
@Test
public void
storeAvailabilityIsModifiedOnRental() {
Movie movie = a.movie.build();
Rental rental =
a.rental.w(movie).build();
Store store =
a.store.w(movie, movie).build();
rental.start(store);
a.rental.build().start(store);
assertEquals(
1, store.getAvailability(movie));
}
}
public class Customer {
private String name;
private List<Rental> rentals =
new ArrayList<Rental>();
public Customer(String name) {
this.name = name;
}
public void addRental(Rental rental) {
rentals.add(rental);
}
public String recentRentals() {
String result = "Recent rentals:";
for (int i=0;
i < rentals.size() && i < 3;
i++) {
result += "\n" +
rentals.get(i).getMovie(
true).getTitle(
"%s starring %s %s", 2);
}
return result;
}
}
public class CustomerTest {
@Test
public void recentRentalsWith2Rentals() {
Movie godfather = mock(Movie.class);
when(godfather
.getTitle("%s starring %s %s", 2))
.thenReturn("Godfather 4");
Rental godfatherRental =
mock(Rental.class);
when(godfatherRental.getMovie(true))
.thenReturn(godfather);
Movie lionKing = mock(Movie.class);
when(lionKing
.getTitle("%s starring %s %s", 2))
.thenReturn("Lion King");
Rental lionKingRental =
mock(Rental.class);
when(lionKingRental.getMovie(true))
.thenReturn(lionKing);
assertEquals(
"Recent rentals:\nGodfather 4\n" +
"Lion King",
a.customer.w(
godfatherRental, lionKingRental)
.build().recentRentals());
}
@Test
public void recentRentalsWith3Rentals() {
// same structure as above, with
// 8 more lines of mocking code,
// 25% longer expected value, and
// 2 lines of adding rentals to customer
}
@Test
public void recentRentalsWith4Rentals() {
// same structure as above, with
// 16 more lines of mocking code,
// 25% longer expected value, and
// 2 lines of adding rentals to customer
}
}
public class CustomerTest {
@Test
public void recentRentalsWith2Rentals() {
Movie godfather = mock(Movie.class);
when(
godfather.getTitle(
anyString(), anyInt()))
.thenReturn("Godfather 4");
Rental godfatherRental =
mock(Rental.class);
when(
godfatherRental.getMovie(anyBoolean()))
.thenReturn(godfather);
Movie lionKing = mock(Movie.class);
when(
lionKing.getTitle(
anyString(), anyInt()))
.thenReturn("Lion King");
Rental lionKingRental =
mock(Rental.class);
when(
lionKingRental.getMovie(anyBoolean()))
.thenReturn(lionKing);
assertEquals(
"Recent rentals:\nGodfather 4\n" +
"Lion King",
a.customer.w(
godfatherRental, lionKingRental)
.build().recentRentals());
}
}
public class CustomerTest {
@Test
public void recentRentalsWith2Rentals() {
Movie godfather = mock(Movie.class);
Rental godfatherRental =
mock(Rental.class);
when(
godfatherRental.getMovie(anyBoolean()))
.thenReturn(godfather);
Movie lionKing = mock(Movie.class);
Rental lionKingRental =
mock(Rental.class);
when(
lionKingRental.getMovie(anyBoolean()))
.thenReturn(lionKing);
assertEquals(
"Recent rentals:\nnull\nnull",
a.customer.w(
godfatherRental, lionKingRental)
.build().recentRentals());
}
}
public class CustomerTest {
@Test
public void recentRentalsWith2Rentals() {
Movie movie = mock(Movie.class);
Rental rental = mock(Rental.class);
when(rental.getMovie(anyBoolean()))
.thenReturn(movie);
assertEquals(
"Recent rentals:\nnull\nnull",
a.customer.w(rental, rental).build()
.recentRentals());
}
}
public class CustomerTest {
@Test
public void recentRentalsWith2Rentals() {
Rental rental = mock(Rental.class);
assertEquals(
"Recent rentals:\nnull\nnull",
a.customer.w(rental, rental).build()
.recentRentals());
}
}
public class Customer {
private String name;
private List<Rental> rentals =
new ArrayList<Rental>();
public Customer(String name) {
this.name = name;
}
public void addRental(Rental rental) {
rentals.add(rental);
}
public String recentRentals() {
String result = "Recent rentals:";
for (int i=0;
i < rentals.size() && i < 3;
i++) {
result +=
"\n" + rentals.get(i).getTitle();
}
return result;
}
}
public class CustomerTest {
@Test
public void recentRentals0Rentals() {
assertEquals(
"Recent rentals:",
a.customer.build().recentRentals());
}
@Test
public void recentRentals1Rental() {
assertEquals(
"Recent rentals:\nnull",
a.customer.w(
mock(Rental.class)).build()
.recentRentals());
}
@Test
public void recentRentals2Rental() {
assertEquals(
"Recent rentals:\nnull\nnull",
a.customer.w(
mock(Rental.class),
mock(Rental.class)).build()
.recentRentals());
}
@Test
public void recentRentals3Rental() {
assertEquals(
"Recent rentals:\nnull\nnull\nnull",
a.customer.w(
mock(Rental.class),
mock(Rental.class),
mock(Rental.class)).build()
.recentRentals());
}
@Test
public void recentRentals4Rental() {
assertEquals(
"Recent rentals:\nnull\nnull\nnull",
a.customer.w(
mock(Rental.class),
mock(Rental.class),
mock(Rental.class),
mock(Rental.class)).build()
.recentRentals());
}
}
public class CustomerTest {
@Test
public void
recentRentalsWith3OrderedRentals() {
assertEquals(
"Recent rentals:"+
"\nGodfather 4\nLion King\nScarface",
a.customer.w(
a.rental.w(a.movie.w("Godfather 4")),
a.rental.w(a.movie.w("Lion King")),
a.rental.w(a.movie.w("Scarface")),
a.rental.w(a.movie.w("Notebook")))
.build().recentRentals());
}
}
public class CustomerTest {
@Test
public void recentRentalsWith4Rentals() {
Movie godfather = mock(Movie.class);
when(godfather
.getTitle("%s starring %s %s", 2))
.thenReturn("Godfather 4");
Rental godfatherRental =
mock(Rental.class);
when(godfatherRental.getMovie(true))
.thenReturn(godfather);
Movie lionKing = mock(Movie.class);
when(lionKing
.getTitle("%s starring %s %s", 2))
.thenReturn("Lion King");
Rental lionKingRental =
mock(Rental.class);
when(lionKingRental.getMovie(true))
.thenReturn(lionKing);
Movie scarface = mock(Movie.class);
when(scarface
.getTitle("%s starring %s %s", 2))
.thenReturn("Scarface");
Rental scarfaceRental =
mock(Rental.class);
when(scarfaceRental.getMovie(true))
.thenReturn(scarface);
Movie notebook = mock(Movie.class);
when(notebook
.getTitle("%s starring %s %s", 2))
.thenReturn("Notebook");
Rental notebookRental =
mock(Rental.class);
when(notebookRental.getMovie(true))
.thenReturn(notebook);
assertEquals(
"Recent rentals:"+
"\nGodfather 4\nLion King" +
"\nScarface",
a.customer.w(
godfatherRental, lionKingRental,
scarfaceRental, notebookRental)
.build().recentRentals());
}
}
public class CustomerTest {
@Test
public void
recentRentalsWith3OrderedRentals() {
assertEquals(
"Recent rentals:"+
"\nGodfather 4\nLion King\nScarface",
a.customer.w(
a.rental.w(a.movie.w("Godfather 4")),
a.rental.w(a.movie.w("Lion King")),
a.rental.w(a.movie.w("Scarface")),
a.rental.w(a.movie.w("Notebook")))
.build().recentRentals());
}
}
public class CustomerTest {
@Test
public void recentRentals0Rentals() {
assertEquals(
"Recent rentals:",
a.customer.build().recentRentals());
}
@Test
public void recentRentals1Rental() {
assertEquals(
"Recent rentals:\nnull",
a.customer.w(
mock(Rental.class)).build()
.recentRentals());
}
@Test
public void recentRentals2Rental() {
assertEquals(
"Recent rentals:\nnull\nnull",
a.customer.w(
mock(Rental.class),
mock(Rental.class)).build()
.recentRentals());
}
@Test
public void recentRentals3Rental() {
assertEquals(
"Recent rentals:\nnull\nnull\nnull",
a.customer.w(
mock(Rental.class),
mock(Rental.class),
mock(Rental.class)).build()
.recentRentals());
}
@Test
public void recentRentals4Rental() {
assertEquals(
"Recent rentals:\nnull\nnull\nnull",
a.customer.w(
mock(Rental.class),
mock(Rental.class),
mock(Rental.class),
mock(Rental.class)).build()
.recentRentals());
}
}
public class MovieTest {
@Test
(expected=IllegalArgumentException.class)
public void invalidTitle() {
a.movie.w(UNKNOWN).build();
}
}
public class MovieTest {
@Test
public void invalidTitle() {
try {
a.movie.w(UNKNOWN).build();
fail();
} catch (Exception ex) {
assertEquals(
IllegalArgumentException.class,
ex.getClass());
}
}
}
public class MovieTest {
@Test
public void invalidTitle() {
Exception e = null;
try {
a.movie.w(UNKNOWN).build();
} catch (Exception ex) {
e = ex;
}
assertEquals(
IllegalArgumentException.class,
e.getClass());
}
}
public class MovieTest {
@Test
public void invalidTitle() {
Runnable runnable = new Runnable() {
public void run() {
a.movie.w(UNKNOWN).build();
}
};
assertThrows(
IllegalArgumentException.class,
runnable);
}
public void assertThrows(
Class ex, Runnable runnable) {
Exception exThrown = null;
try {
runnable.run();
} catch (Exception exThrownActual) {
exThrown = exThrownActual;
}
if (null == exThrown)
fail("No exception thrown");
else
assertEquals(ex, exThrown.getClass());
}
}
public class MovieTest {
Mockery context = new Mockery();
@Test
public void getPointsForDays() {
Movie movie = a.movie.build();
assertEquals(1, movie.getPoints(2));
assertEquals(1, movie.getPoints(3));
}
@Test
(expected=IllegalArgumentException.class)
public void invalidTitle() {
a.movie.w(UNKNOWN).build();
}
@Test
public void getPriceFromPriceInstance() {
final Price price =
context.mock(Price.class);
Movie movie = a.movie.build();
movie.setPrice(price);
context.checking(new Expectations() {{
oneOf(price).getCharge(3);
}});
movie.getCharge(3);
context.assertIsSatisfied();
}
}
public class MovieTest {
@Test
public void getPoints2Days() {
assertEquals(
2, a.movie.build().getPoints(2));
}
@Test
public void getPoints3Days() {
assertEquals(
2, a.movie.build().getPoints(3));
}
@Test
public void invalidTitle() {
Runnable runnable = new Runnable() {
public void run() {
a.movie.w(UNKNOWN).build();
}
};
assertThrows(
IllegalArgumentException.class,
runnable);
}
@Test
public void getPriceFromPriceInstance() {
Price price = mock(Price.class);
Movie movie = a.movie.build();
movie.setPrice(price);
movie.getCharge(3);
verify(price).getCharge(3);
}
}
public class RegularPriceTest {
@Test
public void chargeWithStaticVal() {
assertEquals(
basePrice,
a.regularPrice.build().getCharge(2),
0);
}
@Test
public void chargeWithLocalVal() {
int daysRented = 4;
double charge =
basePrice + (
daysRented - 2) * multiplier;
assertEquals(
charge,
a.regularPrice.build().getCharge(
daysRented),
0);
}
@Test
public void chargeWithLiteral() {
assertEquals(
5.0,
a.regularPrice.build().getCharge(4),
0);
}
}
public class MovieTest {
@Test
public void compareDates() {
Movie godfather =
a.movie.w(
new Date(70261200000L)).build();
assertEquals(
"1972-03-24",
new SimpleDateFormat(
"yyyy-MM-dd").format(
godfather.releaseDate()));
}
}
public class CustomerTest {
@Test
public void statementFor1Rental() {
Rental rental = mock(Rental.class);
Customer customer =
a.customer.w(rental).build();
assertEquals(
expStatement(
"Rental record for %s\n%sAmount " +
"owed is %s\n" +
"You earned %s frequent " +
"renter points",
customer,
rentalInfo(
"\t", "", new Rental[] {rental})),
customer.statement());
}
@Test
public void statementFor2Rentals() {
Rental godfather = mock(Rental.class);
Rental scarface = mock(Rental.class);
Customer customer =
a.customer.w(
godfather, scarface).build();
assertEquals(
expStatement(
"Rental record for %s\n%sAmount " +
"owed is %s\n" +
"You earned %s frequent " +
"renter points",
customer,
rentalInfo(
"\t", "", new Rental[] {
godfather, scarface})),
customer.statement());
}
public static String rentalInfo(
String startsWith,
String endsWith,
Rental[] rentals) {
String result = "";
for (Rental rental : rentals)
result += String.format(
"%s%s%s\n",
startsWith,
rental.getLineItem(),
endsWith);
return result;
}
public static String expStatement(
String formatStr,
Customer customer,
String rentalInfo) {
return String.format(
formatStr,
customer.getName(),
rentalInfo,
customer.getTotalCharge(),
customer.getTotalPoints());
}
}
public class CustomerTest {
@Test
public void statementFor1Rental() {
Customer customer =
a.customer.w(
mock(Rental.class)).build();
assertEquals(
"Rental record for Jim\n" +
"\tnull\n" +
"Amount owed is 0.0\n" +
"You earned 0 frequent renter points",
customer.statement());
}
@Test
public void statementFor2Rentals() {
Customer customer =
a.customer.w(
mock(Rental.class),
mock(Rental.class)).build();
assertEquals(
"Rental record for Jim\n"+
"\tnull\n" +
"\tnull\n" +
"Amount owed is 0.0\n" +
"You earned 0 frequent renter points",
customer.statement());
}
}
public class RentalTest {
@Test
public void
storeMockNeverReceivesRemove() {
Movie movie = mock(Movie.class);
Rental rental =
a.rental.w(movie).build();
Store store = mock(Store.class);
when(
store.getAvailability(
any(Movie.class)))
.thenReturn(0);
rental.start(store);
verify(store, never()).remove(movie);
}
@Test
public void failOnStoreRemove() {
Movie movie = mock(Movie.class);
Rental rental =
a.rental.w(movie).build();
Store store = new Store(
new HashMap<Movie,Integer>()) {
public void remove(Movie movie) {
fail();
}
};
rental.start(store);
}
@Test
public void storeShouldNeverRemove() {
final boolean[] removeCalled = { false };
Movie movie = mock(Movie.class);
Rental rental =
a.rental.w(movie).build();
Store store = new Store(
new HashMap<Movie,Integer>()) {
public void remove(Movie movie) {
removeCalled[0] = true;
}
};
rental.start(store);
assertFalse(removeCalled[0]);
}
}
public class RentalTest {
@Test
public void verifyStoreInteractions() {
Movie movie = mock(Movie.class);
Rental rental =
a.rental.w(movie).build();
Store store = mock(Store.class);
rental.start(store);
verify(store).getAvailability(movie);
verifyNoMoreInteractions(store);
}
}
public class RentalTest {
@Test
public void
storeAvailabilityIsModifiedOnRental() {
Movie movie = a.movie.build();
Rental rental =
a.rental.w(movie).build();
Store store =
a.store.w(movie, movie).build();
rental.start(store);
a.rental.build().start(store);
assertEquals(
1, store.getAvailability(movie));
}
@Test
public void
storeAvailabilityIsUnmodified() {
Movie movie = a.movie.build();
Rental rental =
a.rental.w(movie).build();
Store store = a.store.build();
rental.start(store);
assertEquals(
0, store.getAvailability(movie));
}
}
public class RentalTest extends Store {
public static Movie movie =
mock(Movie.class);
private boolean removeCalled;
public RentalTest() {
super(new HashMap<Movie, Integer>() {{
this.put(movie, 2);
}});
}
@Test
public void removeIsCalled() {
Rental rental =
a.rental.w(movie).build();
rental.start(this);
assertEquals(true, removeCalled);
}
public void remove(Movie movie) {
super.remove(movie);
removeCalled = true;
}
}
public class RentalTest {
@Test(expected=RuntimeException.class)
public void removeIsCalled() {
final Movie movie = mock(Movie.class);
Rental rental =
a.rental.w(movie).build();
HashMap<Movie, Integer> movieMap =
new HashMap<Movie, Integer>() {{
this.put(movie, 2);
}};
Store store =
new Store(movieMap) {
public void remove(Movie movie) {
throw new
RuntimeException("success");
}
};
rental.start(store);
}
}
public class CustomerTest {
Rental godfatherRental;
Rental lionKingRental;
Rental scarfaceRental;
Rental notebookRental;
Customer twoRentals;
Customer fourRentals;
@Before
public void init() {
godfatherRental = mock(Rental.class);
when(godfatherRental.getTitle())
.thenReturn("Godfather 4");
when(godfatherRental.getCharge())
.thenReturn(3.0);
when(godfatherRental.getPoints())
.thenReturn(2);
lionKingRental = mock(Rental.class);
when(lionKingRental.getTitle())
.thenReturn("Lion King");
when(lionKingRental.getCharge())
.thenReturn(2.0);
when(lionKingRental.getPoints())
.thenReturn(1);
scarfaceRental = mock(Rental.class);
when(scarfaceRental.getTitle())
.thenReturn("Scarface");
when(scarfaceRental.getCharge())
.thenReturn(1.0);
when(scarfaceRental.getPoints())
.thenReturn(1);
notebookRental = mock(Rental.class);
when(notebookRental.getTitle())
.thenReturn("Notebook");
when(notebookRental.getCharge())
.thenReturn(6.0);
when(notebookRental.getPoints())
.thenReturn(1);
twoRentals =
a.customer.w(
godfatherRental, lionKingRental)
.build();
fourRentals =
a.customer.w(
godfatherRental, lionKingRental,
scarfaceRental, notebookRental)
.build();
}
@Test
public void recentRentalsWith2Rentals() {
assertEquals(
"Recent rentals:"+
"\nGodfather 4\nLion King",
twoRentals.recentRentals());
}
@Test
public void recentRentalsWith4Rentals() {
assertEquals(
"Recent rentals:"+
"\nGodfather 4\nLion King\nScarface",
fourRentals.recentRentals());
}
@Test
public void totalChargeWith2Rentals() {
assertEquals(
5.0,
twoRentals.getTotalCharge(),
0);
}
@Test
public void totalChargeWith4Rentals() {
assertEquals(
12.0,
fourRentals.getTotalCharge(),
0);
}
@Test
public void totalPointsWith2Rentals() {
assertEquals(
3,
twoRentals.getTotalPoints());
}
@Test
public void totalPointsWith4Rentals() {
assertEquals(
5,
fourRentals.getTotalPoints());
}
@Test
public void getName() {
assertEquals(
"Jim", twoRentals.getName());
}
}
public class CustomerTest {
Rental godfatherRental;
Rental lionKingRental;
Rental scarfaceRental;
Rental notebookRental;
Customer twoRentals;
Customer fourRentals;
@Before
public void init() {
godfatherRental = mock(Rental.class);
when(godfatherRental.getTitle())
.thenReturn("Godfather 4");
when(godfatherRental.getCharge())
.thenReturn(3.0);
when(godfatherRental.getPoints())
.thenReturn(2);
lionKingRental = mock(Rental.class);
when(lionKingRental.getTitle())
.thenReturn("Lion King");
when(lionKingRental.getCharge())
.thenReturn(2.0);
when(lionKingRental.getPoints())
.thenReturn(1);
scarfaceRental = mock(Rental.class);
when(scarfaceRental.getTitle())
.thenReturn("Scarface");
when(scarfaceRental.getCharge())
.thenReturn(1.0);
when(scarfaceRental.getPoints())
.thenReturn(1);
notebookRental = mock(Rental.class);
when(notebookRental.getTitle())
.thenReturn("Notebook");
when(notebookRental.getCharge())
.thenReturn(6.0);
when(notebookRental.getPoints())
.thenReturn(1);
twoRentals =
a.customer.w(
godfatherRental, lionKingRental)
.build();
fourRentals =
a.customer.w(
godfatherRental, lionKingRental,
scarfaceRental, notebookRental)
.build();
}
@Test
public void recentRentalsWith2Rentals() {
assertEquals(
"Recent rentals:"+
"\nGodfather 4\nLion King",
twoRentals.recentRentals());
}
@Test
public void recentRentalsWith4Rentals() {
assertEquals(
"Recent rentals:"+
"\nGodfather 4\nLion King\nScarface",
fourRentals.recentRentals());
}
@Test
public void totalChargeWith2Rentals() {
assertEquals(
5.0,
twoRentals.getTotalCharge(),
0);
}
@Test
public void totalChargeWith4Rentals() {
assertEquals(
12.0,
fourRentals.getTotalCharge(),
0);
}
@Test
public void totalPointsWith2Rentals() {
assertEquals(
3,
twoRentals.getTotalPoints());
}
@Test
public void totalPointsWith4Rentals() {
assertEquals(
5,
fourRentals.getTotalPoints());
}
@Test
public void getName() {
assertEquals(
"Jim", twoRentals.getName());
}
}
public class CustomerTest {
@Test
public void recentRentalsWith2Rentals() {
Rental godfatherRental =
mock(Rental.class);
when(godfatherRental.getTitle())
.thenReturn("Godfather 4");
Rental lionKingRental =
mock(Rental.class);
when(lionKingRental.getTitle())
.thenReturn("Lion King");
assertEquals(
"Recent rentals:"+
"\nGodfather 4\nLion King",
a.customer.w(
godfatherRental, lionKingRental)
.build().recentRentals());
}
@Test
public void recentRentalsWith4Rentals() {
Rental godfatherRental =
mock(Rental.class);
when(godfatherRental.getTitle())
.thenReturn("Godfather 4");
Rental lionKingRental =
mock(Rental.class);
when(lionKingRental.getTitle())
.thenReturn("Lion King");
Rental scarfaceRental =
mock(Rental.class);
when(scarfaceRental.getTitle())
.thenReturn("Scarface");
Rental notebookRental =
mock(Rental.class);
when(notebookRental.getTitle())
.thenReturn("Notebook");
assertEquals(
"Recent rentals:"+
"\nGodfather 4\nLion King\nScarface",
a.customer.w(
godfatherRental, lionKingRental,
scarfaceRental, notebookRental)
.build().recentRentals());
}
@Test
public void totalChargeWith2Rentals() {
Rental godfatherRental =
mock(Rental.class);
when(godfatherRental.getCharge())
.thenReturn(3.0);
Rental lionKingRental =
mock(Rental.class);
when(lionKingRental.getCharge())
.thenReturn(2.0);
assertEquals(
5.0,
a.customer.w(
godfatherRental, lionKingRental)
.build().getTotalCharge(),
0);
}
@Test
public void totalChargeWith4Rentals() {
Rental godfatherRental =
mock(Rental.class);
when(godfatherRental.getCharge())
.thenReturn(3.0);
Rental lionKingRental =
mock(Rental.class);
when(lionKingRental.getCharge())
.thenReturn(2.0);
Rental scarfaceRental =
mock(Rental.class);
when(scarfaceRental.getCharge())
.thenReturn(1.0);
Rental notebookRental =
mock(Rental.class);
when(notebookRental.getCharge())
.thenReturn(6.0);
assertEquals(
12.0,
a.customer.w(
godfatherRental, lionKingRental,
scarfaceRental, notebookRental)
.build().getTotalCharge(),
0);
}
@Test
public void totalPointsWith2Rentals() {
Rental godfatherRental =
mock(Rental.class);
when(godfatherRental.getPoints())
.thenReturn(2);
Rental lionKingRental =
mock(Rental.class);
when(lionKingRental.getPoints())
.thenReturn(1);
assertEquals(
3,
a.customer.w(
godfatherRental, lionKingRental)
.build().getTotalPoints());
}
@Test
public void totalPointsWith4Rentals() {
Rental godfatherRental =
mock(Rental.class);
when(godfatherRental.getPoints())
.thenReturn(2);
Rental lionKingRental =
mock(Rental.class);
when(lionKingRental.getPoints())
.thenReturn(1);
Rental scarfaceRental =
mock(Rental.class);
when(scarfaceRental.getPoints())
.thenReturn(1);
Rental notebookRental =
mock(Rental.class);
when(notebookRental.getPoints())
.thenReturn(1);
assertEquals(
5,
a.customer.w(
godfatherRental, lionKingRental,
scarfaceRental, notebookRental)
.build().getTotalPoints());
}
@Test
public void getName() {
assertEquals(
"Jim",
a.customer.build().getName());
}
}
public class PidWriter {
public static void writePid(
String filename,
RuntimeMXBean bean) {
try {
writePidtoFile(filename, bean);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static void writePidtoFile(
String filename,
RuntimeMXBean bean) throws IOException {
FileWriter writer =
new FileWriter(filename);
try {
String runtimeName = bean.getName();
writer.write(
runtimeName.substring(
0, runtimeName.indexOf('@')));
}
finally {
writer.close();
}
}
}
public class PidWriterTest {
@Test
public void writePid() throws Exception {
RuntimeMXBean bean =
mock(RuntimeMXBean.class);
when(bean.getName()).thenReturn("12@X");
PidWriter.writePid(
"/tmp/sample.pid", bean);
assertEquals(
"12",
Files.readAllLines(
Paths.get("/tmp/sample.pid"),
Charset.defaultCharset()).get(0));
}
}
public class FileWriterGateway
extends FileWriter {
public static boolean disallowAccess =
false;
public FileWriterGateway(
String filename) throws IOException {
super(filename);
if (disallowAccess) {
throw new RuntimeException(
"access disallowed");
}
}
}
public class PidWriter {
public static void writePid(
String filename,
RuntimeMXBean bean) {
try {
writePidtoFile(filename, bean);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static void writePidtoFile(
String filename,
RuntimeMXBean bean) throws IOException {
FileWriterGateway writer =
new FileWriterGateway(filename);
try {
String runtimeName = bean.getName();
writer.write(
runtimeName.substring(
0, runtimeName.indexOf('@')));
}
finally {
writer.close();
}
}
}
public class PidWriterTest extends Solitary {
@Test
public void writePid() throws Exception {
RuntimeMXBean bean =
mock(RuntimeMXBean.class);
when(bean.getName()).thenReturn("12@X");
PidWriter.writePid(
"/tmp/sample.pid", bean);
assertEquals(
"12",
Files.readAllLines(
Paths.get("/tmp/sample.pid"),
Charset.defaultCharset()).get(0));
}
}
public class Solitary {
@Before
public void setup() {
FileWriterGateway.disallowAccess = true;
}
}
public class PidWriterTest extends Solitary {
@Test
public void writePid() throws Exception {
RuntimeMXBean bean =
mock(RuntimeMXBean.class);
when(bean.getName()).thenReturn("12@X");
FileWriterGateway facade =
mock(FileWriterGateway.class);
PidWriter.writePid(facade, bean);
verify(facade).write("12");
}
}
public class PidWriter {
public static void writePid(
String filename,
RuntimeMXBean bean) {
try {
FileWriterGateway writer =
new FileWriterGateway(filename);
writePid(writer, bean);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public static void writePid(
FileWriterGateway facade,
RuntimeMXBean bean) {
try {
writePidtoFile(facade, bean);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static void writePidtoFile(
FileWriterGateway facade,
RuntimeMXBean bean) throws IOException {
try {
String runtimeName = bean.getName();
facade.write(
runtimeName.substring(
0, runtimeName.indexOf('@')));
} catch (IOException e) {
throw new RuntimeException(e);
}
finally {
facade.close();
}
}
}
public class PidWriterTest extends Sociable {
@Test
public void writePid() throws Exception {
RuntimeMXBean bean =
mock(RuntimeMXBean.class);
when(bean.getName()).thenReturn("12@X");
PidWriter.writePid(
"/tmp/wewut/sample.pid", bean);
assertEquals(
"12",
Files.readAllLines(
Paths.get("/tmp/wewut/sample.pid"),
Charset.defaultCharset()).get(0));
}
}
public class Sociable {
@Before
public void setup()
throws Exception {
Process p;
p = Runtime.getRuntime().exec(
"rm -rf /tmp/wewut");
p.waitFor();
p = Runtime.getRuntime().exec(
"mkdir -p /tmp/wewut");
p.waitFor();
}
}
public class Rental {
Movie movie;
private int daysRented;
private boolean started;
private DateTime creationDateTime;
public Rental(
Movie movie,
int daysRented,
DateTime creationDateTime) {
this.movie = movie;
this.daysRented = daysRented;
this.creationDateTime = creationDateTime;
}
public Rental(Movie movie, int daysRented) {
this(movie, daysRented, new DateTime());
}
public DateTime getCreationDateTime() {
return creationDateTime;
}
}
public class RentalTest {
@Test
public void creationDateTimeNow() {
DateTimeUtils.setCurrentMillisFixed(1000);
Rental rental = a.rental.build();
assertEquals(
1000,
rental.getCreationDateTime()
.getMillis());
}
@Test
public void creationDateTimeSet() {
Rental rental =
a.rental.w(
new DateTime(199)).build();
assertEquals(
199,
rental.getCreationDateTime()
.getMillis());
}
}
public class RentalTest {
@Test
public void creationDateTimeNow() {
DateTimeUtils.setCurrentMillisFixed(1000);
Rental rental = a.rental.build();
assertEquals(
1000,
rental.getCreationDateTime()
.getMillis());
DateTimeUtils.setCurrentMillisSystem();
}
@Test
public void creationDateTimeSet() {
Rental rental =
a.rental.w(
new DateTime(199)).build();
assertEquals(
199,
rental.getCreationDateTime()
.getMillis());
}
}
public class Solitary {
@Before
public void setup() {
FileWriterGateway.disallowAccess = true;
DateTimeUtils.setCurrentMillisFixed(1000);
}
}
public class RentalTest extends Solitary {
@Test
public void creationDateTimeNow() {
Rental rental = a.rental.build();
assertEquals(
1000,
rental.getCreationDateTime()
.getMillis());
}
@Test
public void creationDateTimeSet() {
Rental rental =
a.rental.w(
new DateTime(199)).build();
assertEquals(
199,
rental.getCreationDateTime()
.getMillis());
}
}
public class CustomerTest {
@Test
public void noRentalsStatement() {
assertEquals(
"Rental record for Jim\nAmount owed " +
"is 0.0\n" +
"You earned 0 frequent renter points",
a.customer.build().statement());
}
@Test
public void oneRentalStatement() {
assertEquals(
"Rental record for Jim\n" +
"\tGodfather 4 9.0\n" +
"Amount owed is 9.0\n" +
"You earned 2 frequent renter points",
a.customer.w(
a.rental).build().statement());
}
@Test
public void twoRentalsStatement() {
assertEquals(
"Rental record for Jim\n" +
"\tGodfather 4 9.0\n" +
"\tGodfather 4 9.0\n" +
"Amount owed is 18.0\n" +
"You earned 4 frequent renter points",
a.customer.w(
a.rental, a.rental).build()
.statement());
}
@Test
public void noRentalsGetTotalPoints() {
assertEquals(
0,
a.customer.build().getTotalPoints());
}
@Test
public void oneRentalGetTotalPoints() {
assertEquals(
2,
a.customer.w(
a.rental).build().getTotalPoints());
}
@Test
public void twoRentalsGetTotalPoints() {
assertEquals(
4,
a.customer.w(a.rental, a.rental)
.build()
.getTotalPoints());
}
// 3 tests for htmlStatement()
// left to the imagination
}
public class RentalTest {
@Test
public void getPointsFromMovie() {
assertEquals(
2, a.rental.build().getPoints());
}
}
public class MovieTest {
@Test
public void getPoints() {
assertEquals(
2, a.movie.build().getPoints(2));
}
}
public class NewReleasePrice extends Price {
@Override
public double getCharge(int daysRented) {
return daysRented * 3;
}
@Override
public int getPoints(int daysRented) {
if (daysRented > 1)
return 3; // was 2
return 1;
}
}
public class CustomerTest {
@Test
public void noRentalsStatement() {
assertEquals(
"Rental record for Jim\nAmount owed " +
"is 0.0\n" +
"You earned 0 frequent renter points",
a.customer.build().statement());
}
@Test
public void oneRentalStatement() {
Rental rental = mock(Rental.class);
when(rental.getLineItem())
.thenReturn("Godfather 4 9.0");
when(rental.getCharge())
.thenReturn(9.0);
when(rental.getPoints())
.thenReturn(2);
assertEquals(
"Rental record for Jim\n" +
"\tGodfather 4 9.0\n" +
"Amount owed is 9.0\n" +
"You earned 2 frequent renter points",
a.customer.w(rental).build()
.statement());
}
@Test
public void twoRentalsStatement() {
Rental one = mock(Rental.class);
when(one.getLineItem())
.thenReturn("Godfather 4 9.0");
when(one.getCharge())
.thenReturn(9.0);
when(one.getPoints())
.thenReturn(2);
Rental two = mock(Rental.class);
when(two.getLineItem())
.thenReturn("Godfather 4 9.0");
when(two.getCharge())
.thenReturn(9.0);
when(two.getPoints())
.thenReturn(2);
assertEquals(
"Rental record for Jim\n" +
"\tGodfather 4 9.0\n" +
"\tGodfather 4 9.0\n" +
"Amount owed is 18.0\n" +
"You earned 4 frequent renter points",
a.customer.w(one, two).build()
.statement());
}
@Test
public void noRentalsGetTotalPoints() {
assertEquals(
0,
a.customer.build().getTotalPoints());
}
@Test
public void oneRentalGetTotalPoints() {
Rental rental = mock(Rental.class);
when(rental.getPoints())
.thenReturn(2);
assertEquals(
2,
a.customer.w(
rental).build().getTotalPoints());
}
@Test
public void twoRentalsGetTotalPoints() {
Rental one = mock(Rental.class);
when(one.getPoints())
.thenReturn(2);
Rental two = mock(Rental.class);
when(two.getPoints())
.thenReturn(3);
assertEquals(
5,
a.customer.w(
one, two).build().getTotalPoints());
}
}
public class RentalTest {
@Test
public void getPointsFromMovie() {
Movie movie = mock(Movie.class);
when(movie.getPoints(2))
.thenReturn(2);
assertEquals(
2,
a.rental.w(
2).w(movie).build().getPoints());
}
}
public class Rental {
Movie movie;
private int daysRented;
private boolean started;
public Rental(
Movie movie, int daysRented) {
this.movie = movie;
this.daysRented = daysRented;
}
public double getCharge() {
return movie.getCharge(daysRented);
}
public int getPoints() {
return
movie.getPoints(daysRented, false);
}
public int getPoints(boolean vipFlag) {
return
movie.getPoints(daysRented, vipFlag);
}
public String getLineItem() {
return
movie.getTitle() + " " + getCharge();
}
}
public class CustomerTest {
@Test
public void noRentalsStatement() {
assertEquals(
"Rental record for Jim\nAmount owed " +
"is 0.0\n" +
"You earned 0 frequent renter points",
a.customer.build().statement());
}
@Test
public void oneRentalStatement() {
Rental rental = mock(Rental.class);
assertEquals(
"Rental record for Jim\n\tnull\n" +
"Amount owed is 0.0\n" +
"You earned 0 frequent renter points",
a.customer.w(
rental).build().statement());
}
@Test
public void twoRentalsStatement() {
Rental rental = mock(Rental.class);
assertEquals(
"Rental record for Jim\n\tnull\n" +
"\tnull\nAmount owed is 0.0\n" +
"You earned 0 frequent renter points",
a.customer.w(
rental, rental).build().statement());
}
@Test
public void noRentalsGetTotalPoints() {
assertEquals(
0,
a.customer.build().getTotalPoints());
}
@Test
public void oneRentalGetTotalPoints() {
Rental rental = mock(Rental.class);
when(rental.getPoints())
.thenReturn(2);
assertEquals(
2,
a.customer.w(
rental).build().getTotalPoints());
}
@Test
public void twoRentalsGetTotalPoints() {
Rental one = mock(Rental.class);
when(one.getPoints())
.thenReturn(2);
Rental two = mock(Rental.class);
when(two.getPoints())
.thenReturn(3);
assertEquals(
5,
a.customer.w(
one, two).build().getTotalPoints());
}
}
public class MovieTest {
@Test
public void getChargeForChildrens() {
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(1),
0);
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(2),
0);
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(3),
0);
assertEquals(
3.0,
a.movie.w(
CHILDREN).build().getCharge(4),
0);
assertEquals(
4.5,
a.movie.w(
CHILDREN).build().getCharge(5),
0);
}
}
public class Movie {
public enum Type {
REGULAR, NEW_RELEASE, CHILDREN, UNKNOWN;
}
private String title;
Price price;
public Movie(
String title, Movie.Type priceCode) {
this.title = title;
setPriceCode(priceCode);
}
public String getTitle() {
return title;
}
private void setPriceCode(
Movie.Type priceCode) {
switch (priceCode) {
case CHILDREN:
price = new ChildrensPrice();
break;
case NEW_RELEASE:
price = new NewReleasePrice();
break;
case REGULAR:
price = new RegularPrice();
break;
default:
throw new IllegalArgumentException(
"invalid price code");
}
}
public double getCharge(int daysRented) {
return price.getCharge(daysRented);
}
public int getPoints(int daysRented) {
return price.getPoints(daysRented);
}
}
public class ChildrensPrice extends Price {
@Override
public double getCharge(int daysRented) {
double amount = 1.5;
if (daysRented > 2) // *was 3*
amount += (daysRented - 2) * 1.5;
return amount;
}
}
public class JavaTest {
@Test
public void arrayListGet() {
ArrayList<Integer> list =
new ArrayList<Integer>();
list.add(1);
assertEquals(
Integer.valueOf(1), list.get(0));
}
@Test
public void hashMapGet() {
HashMap<Integer, String> map =
new HashMap<Integer, String>();
map.put(1, "a str");
assertEquals("a str", map.get(1));
}
@Test
public void throwCatch() {
Exception ex = null;
try {
throw new RuntimeException("ex");
} catch (Exception eCaught) {
ex = eCaught;
}
assertEquals("ex", ex.getMessage());
}
}
public class JodaTest {
@Test
public void parseStr() {
assertEquals(
286347600000L,
DateTime.parse(
"1979-01-28").getMillis());
}
}
public class Assert {
public static void assertThrows(
Class ex, Runnable runnable) {
Exception exThrown = null;
try {
runnable.run();
} catch (Exception exThrownActual) {
exThrown = exThrownActual;
}
if (null == exThrown)
fail("No exception thrown");
else
assertEquals(ex, exThrown.getClass());
}
}
public class MovieTest {
@Test
public void invalidTitleCustomAssertion() {
assertThrows(
IllegalArgumentException.class,
() -> a.movie.w(UNKNOWN).build());
}
@Test
public void invalidTitleWithoutCA() {
Exception e = null;
try {
a.movie.w(UNKNOWN).build();
} catch (Exception ex) {
e = ex;
}
assertEquals(
IllegalArgumentException.class,
e.getClass());
}
}
public class AssertTest {
@Test
public void failIfNoThrow() {
AssertionError e = null;
try {
assertThrows(
IllegalArgumentException.class,
mock(Runnable.class));
} catch (AssertionError ex) {
e = ex;
}
assertEquals(
AssertionError.class,
e.getClass());
}
@Test
public void failWithMessageIfNoThrow() {
AssertionError e = null;
try {
assertThrows(
IllegalArgumentException.class,
mock(Runnable.class));
} catch (AssertionError ex) {
e = ex;
}
assertEquals(
"No exception thrown",
e.getMessage());
}
@Test
public void failIfClassMismatch() {
AssertionError e = null;
try {
assertThrows(
IllegalArgumentException.class,
() -> {
throw new RuntimeException("");});
} catch (AssertionError ex) {
e = ex;
}
assertEquals(
AssertionError.class,
e.getClass());
}
@Test
public void failWithMessageIfClassWrong() {
AssertionError e = null;
try {
assertThrows(
IllegalArgumentException.class,
() -> {
throw new RuntimeException("");});
} catch (AssertionError ex) {
e = ex;
}
assertEquals(
"expected:<class java.lang."+
"IllegalArgumentException> "+
"but was:<class java.lang."+
"RuntimeException>",
e.getMessage());
}
@Test
public void passWithCorrectException() {
AssertionError e = null;
try {
assertThrows(
RuntimeException.class,
() -> {
throw new RuntimeException("");});
} catch (AssertionError ex) {
e = ex;
}
assertEquals(null, e);
}
}
public class MovieTest {
@Test
public void compareDates() {
Movie godfather =
a.movie.w(
new Date(70261200000L)).build();
assertEquals(
"1972-03-24",
new SimpleDateFormat(
"yyyy-MM-dd").format(
godfather.releaseDate()));
}
}
public class Assert {
public static void assertDateWithFormat(
String expected,
String format,
Date dt) {
assertEquals(
expected,
new SimpleDateFormat(
format).format(dt));
}
}
public class MovieTest {
@Test
public void compareDates() {
Movie godfather =
a.movie.w(
new Date(70261200000L)).build();
assertDateWithFormat(
"1972-03-24",
"yyyy-MM-dd",
godfather.releaseDate());
}
}
public class Money {
private BigDecimal val;
public Money(double val) {
this(BigDecimal.valueOf(val));
}
public Money(BigDecimal val) {
this.val = val;
}
public Money add(double d) {
return new Money(
val.add(BigDecimal.valueOf(d)));
}
public Money add(Money m) {
return new Money(val.add(m.val));
}
public double toDouble() {
return val
.setScale(2, BigDecimal.ROUND_HALF_UP)
.doubleValue();
}
}
public class MoneyTest {
@Test
public void doubleAddition() {
assertEquals(
11.0,
a.money.w(1.0).build().add(
10.0).toDouble(),
0);
}
@Test
public void moneyAddition() {
assertEquals(
11.0,
a.money.w(1.0).build().add(
a.money.w(10.0).build()).toDouble(),
0);
}
@Test
public void oneDecimalToDouble() {
assertEquals(
1.0,
a.money.w(1.0).build().toDouble(),
0);
}
@Test
public void twoDecimalToDouble() {
assertEquals(
1.12,
a.money.w(1.12).build().toDouble(),
0);
}
@Test
public void thrDecimalUpToDouble() {
assertEquals(
1.12,
a.money.w(1.123).build().toDouble(),
0);
}
@Test
public void thrDecimalDownToDouble() {
assertEquals(
1.13,
a.money.w(1.125).build().toDouble(),
0);
}
}
public class Movie {
public enum Type {
REGULAR, NEW_RELEASE, CHILDREN;
}
private String title;
Price price;
public Movie(
String title, Movie.Type priceCode) {
this.title = title;
setPriceCode(priceCode);
}
private void setPriceCode(
Movie.Type priceCode) {
switch (priceCode) {
case CHILDREN:
price = new ChildrensPrice();
break;
case NEW_RELEASE:
price = new NewReleasePrice();
break;
case REGULAR:
price = new RegularPrice();
break;
}
}
public Money getCharge(int daysRented) {
return price.getCharge(daysRented);
}
}
public class MovieTest {
@Test
public void getChargeForChildrens1Day() {
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(
1).toDouble(),
0);
}
@Test
public void getChargeForChildrens2Day() {
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(
2).toDouble(),
0);
}
@Test
public void getChargeForChildrens3Day() {
assertEquals(
1.5,
a.movie.w(
CHILDREN).build().getCharge(
3).toDouble(),
0);
}
@Test
public void getChargeForChildrens4Day() {
assertEquals(
3.0,
a.movie.w(
CHILDREN).build().getCharge(
4).toDouble(),
0);
}
@Test
public void getChargeForChildrens5Day() {
assertEquals(
4.5,
a.movie.w(
CHILDREN).build().getCharge(
5).toDouble(),
0);
}
}
public class Assert {
public static void assertMoney(
double d, Money m) {
assertEquals(d, m.toDouble(), 0);
}
}
public class MoneyTest {
@Test
public void doubleAddition() {
assertMoney(
11.0, a.money.w(1.0).build().add(10.0));
}
@Test
public void moneyAddition() {
assertMoney(
11.0,
a.money.w(1.0).build().add(
a.money.w(10.0).build()));
}
@Test
public void oneDecimalToDouble() {
assertMoney(
1.0, a.money.w(1.0).build());
}
@Test
public void twoDecimalToDouble() {
assertMoney(
1.12, a.money.w(1.12).build());
}
@Test
public void thrDecimalUpToDouble() {
assertMoney(
1.12, a.money.w(1.123).build());
}
@Test
public void thrDecimalDownToDouble() {
assertMoney(
1.13, a.money.w(1.125).build());
}
}
public class MovieTest {
@Test
public void getChargeForChildrens1Day() {
assertMoney(
1.5,
a.movie.w(
CHILDREN).build().getCharge(1));
}
@Test
public void getChargeForChildrens2Day() {
assertMoney(
1.5,
a.movie.w(
CHILDREN).build().getCharge(2));
}
@Test
public void getChargeForChildrens3Day() {
assertMoney(
1.5,
a.movie.w(
CHILDREN).build().getCharge(3));
}
@Test
public void getChargeForChildrens4Day() {
assertMoney(
3.0,
a.movie.w(
CHILDREN).build().getCharge(4));
}
@Test
public void getChargeForChildrens5Day() {
assertMoney(
4.5,
a.movie.w(
CHILDREN).build().getCharge(5));
}
}
public class Rental {
Movie movie;
private int daysRented;
public Rental(
Movie movie, int daysRented) {
this.movie = movie;
this.daysRented = daysRented;
}
public Money getCharge() {
return movie.getCharge(daysRented);
}
}
public class RentalTest {
@Test
public void getChargeFromMovie() {
Movie movie = mock(Movie.class);
when(movie.getCharge(any(Integer.class)))
.thenReturn(a.money.w(1.5).build());
assertMoney(
1.5,
a.rental.w(movie).build().getCharge());
}
}
public class Customer {
private List<Rental> rentals =
new ArrayList<Rental>();
public void addRental(Rental rental) {
rentals.add(rental);
}
public Money getTotalCharge() {
Money total = new Money(0.0);
for (Rental rental : rentals)
total = total.add(rental.getCharge());
return total;
}
}
public class CustomerTest {
@Test
public void chargeForNoRentals() {
assertMoney(
0.0,
a.customer.build().getTotalCharge());
}
@Test
public void chargeForOneRental() {
Rental rental = mock(Rental.class);
when(rental.getCharge())
.thenReturn(a.money.w(2.0).build());
assertMoney(
2.0,
a.customer.w(
rental).build().getTotalCharge());
}
@Test
public void chargeForTwoRentals() {
Rental rental1 = mock(Rental.class);
when(rental1.getCharge())
.thenReturn(a.money.w(2.2).build());
Rental rental2 = mock(Rental.class);
when(rental2.getCharge())
.thenReturn(a.money.w(3.5).build());
assertMoney(
5.7,
a.customer.w(
rental1,
rental2).build().getTotalCharge());
}
}
public class a {
public static CustomerBuilder customer =
new CustomerBuilder();
public static MoneyBuilder money =
new MoneyBuilder();
public static class CustomerBuilder {
Rental[] rentals;
CustomerBuilder() {
this(new Rental[0]);
}
CustomerBuilder(Rental[] rentals) {
this.rentals = rentals;
}
public CustomerBuilder w(
Rental... rentals) {
return new CustomerBuilder(rentals);
}
public Customer build() {
Customer result = new Customer();
for (Rental rental : rentals) {
result.addRental(rental);
}
return result;
}
}
public static class MoneyBuilder {
final double val;
MoneyBuilder() {
this(1.0);
}
MoneyBuilder(double val) {
this.val = val;
}
public MoneyBuilder w(double val) {
return new MoneyBuilder(val);
}
public Money build() {
return new Money(val);
}
}
}
public class CustomerTest {
@Test
public void chargeForTwoRentals() {
Rental rental1 = mock(Rental.class);
when(rental1.getCharge())
.thenReturn(a.money.w(2.2).build());
Rental rental2 = mock(Rental.class);
when(rental2.getCharge())
.thenReturn(a.money.w(3.5).build());
assertMoney(
5.7,
a.customer.w(
rental1,
rental2).build().getTotalCharge());
}
}
public class CustomerTest {
@Test
public void chargeForTwoRentals() {
Rental rental1 = mock(Rental.class);
when(rental1.getCharge())
.thenReturn(a.money.w(2.2).build());
Rental rental2 = mock(Rental.class);
when(rental2.getCharge())
.thenReturn(a.money.w(3.5).build());
Customer customer = a.customer.build();
customer.addRental(rental1);
customer.addRental(rental2);
assertMoney(
5.7, customer.getTotalCharge());
}
}
public class Customer {
private List<Rental> rentals =
new ArrayList<Rental>();
public void addRental(Rental rental) {
rentals.add(rental);
}
public Money getTotalCharge() {
Money total = new Money(0.0);
for (Rental rental : rentals)
total = total.add(rental.getCharge());
return total;
}
}
public class Customer {
private ArrayList<Rental> rentals =
new ArrayList<Rental>();
public Customer addRentals(
Rental... newRentals) {
rentals.addAll(Arrays.asList(newRentals));
return this;
}
public Money getTotalCharge() {
Money total = new Money(0.0);
for (Rental rental : rentals)
total = total.add(rental.getCharge());
return total;
}
}
public class CustomerTest {
@Test
public void chargeForTwoRentals() {
Rental rental1 = mock(Rental.class);
when(rental1.getCharge())
.thenReturn(a.money.w(2.2).build());
Rental rental2 = mock(Rental.class);
when(rental2.getCharge())
.thenReturn(a.money.w(3.5).build());
assertMoney(
5.7,
a.customer.build().addRentals(
rental1, rental2).getTotalCharge());
}
}
public class MockitoExtensions {
@SuppressWarnings("unchecked")
public static <T> T create(
Object methodCall) {
when(methodCall)
.thenReturn(
StubBuilder.current.returnValue);
return (T)
StubBuilder.current.mockInstance;
}
public static <T> StubBuilder<T> stub(
Class<T> klass) {
return new StubBuilder<T>(mock(klass));
}
public static class StubBuilder<T> {
public static StubBuilder current;
public final T mockInstance;
private Object returnValue;
public StubBuilder(T mockInstance) {
current = this;
this.mockInstance = mockInstance;
}
public T from() {
return mockInstance;
}
public StubBuilder<T> returning(
Object returnValue) {
this.returnValue = returnValue;
return this;
}
}
}
public class CustomerTest {
@Test
public void chargeForTwoRentals() {
assertMoney(
5.7,
a.customer.build().addRentals(
create(
stub(Rental.class)
.returning(a.money.w(2.2).build())
.from().getCharge()),
create(
stub(Rental.class)
.returning(a.money.w(3.5).build())
.from().getCharge()))
.getTotalCharge());
}
}
public class MockitoExtensions {
public static <T> T stub(
Class<T> klass,
Function<T,Object> f,
Object returnVal) {
try {
T result = mock(klass);
when(f.apply(result))
.thenReturn(returnVal);
return result;
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}
public class CustomerTest {
@Test
public void chargeForTwoRentals() {
assertMoney(
5.7,
a.customer.build().addRentals(
stub(Rental.class,
s -> s.getCharge(),
a.money.w(2.2).build()),
stub(Rental.class,
s -> s.getCharge(),
a.money.w(3.5).build()))
.getTotalCharge());
}
}