Skip to content

Instantly share code, notes, and snippets.

@JayBazuzi
Last active August 29, 2015 14:17
Show Gist options
  • Save JayBazuzi/c48ba6301f9178d823be to your computer and use it in GitHub Desktop.
Save JayBazuzi/c48ba6301f9178d823be to your computer and use it in GitHub Desktop.
Code samples from Working Effectively with Unit Tests (https://leanpub.com/wewut)
[TestClass]
public class CustomerTest
{
private const string DavidName = "David";
private const string JohnName = "John";
private const string PatName = "Pat";
private const string SteveName = "Steve";
private readonly Customer[] _customers;
private readonly Customer _david;
private readonly Customer _john;
private readonly Customer _pat;
private readonly Customer _steve;
public CustomerTest()
{
_david = ObjectMother.CustomerWithNoRentals(DavidName);
_john = ObjectMother.CustomerWithOneNewRelease(JohnName);
_pat = ObjectMother.CustomerWithOneOfEachRentalGenre(PatName);
_steve = ObjectMother.CustomerWithOneNewReleaseAndOneRegular(SteveName);
_customers = new[] {_david, _john, _steve, _pat};
}
[TestMethod]
public void GetName()
{
Assert.AreEqual(DavidName, _david.GetName());
Assert.AreEqual(JohnName, _john.GetName());
Assert.AreEqual(SteveName, _steve.GetName());
Assert.AreEqual(PatName, _pat.GetName());
}
[TestMethod]
public void Statement()
{
foreach (var t in _customers)
{
var expected = ExpStatement(@"Rental record for {0}
{1}Amount owed is {2}
You earned {3} frequent renter points",
t, RentalInfo("\t", "", t.GetRentals()));
var actual = t.Statement();
Assert.AreEqual(expected, actual);
}
}
[TestMethod]
public void HtmlStatement()
{
foreach (var customer in _customers)
{
Assert.AreEqual(
ExpStatement(
"<h1>Rental record for " + "<em>{0}</em></h1>\r\n{1}" + "<p>Amount owed is <em>{2}</em>" +
"</p>\r\n<p>You earned <em>{3}" + " frequent renter points</em></p>",
customer,
RentalInfo("<p>", "</p>", customer.GetRentals())),
customer.HtmlStatement());
}
}
[TestMethod]
[ExpectedException(typeof (ArgumentException))]
public void InvalidTitle()
{
ObjectMother.CustomerWithNoRentals("Bob")
.AddRental(new Rental(new Movie("Crazy, Stupid, Love.", Movie.Genre.Unknown), 4));
}
public static string RentalInfo(string startsWith, string endsWith, List<Rental> rentals)
{
var result = "";
foreach (var rental in rentals)
result += string.Format("{0}{1} {2}{3}\r\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 CustomerWithOneOfEachRentalGenre(string name)
{
var result = CustomerWithOneNewReleaseAndOneRegular(name);
result.AddRental(new Rental(new Movie("Lion King", Movie.Genre.Children), 3));
return result;
}
public static Customer CustomerWithOneNewReleaseAndOneRegular(string n)
{
var result = CustomerWithOneNewRelease(n);
result.AddRental(new Rental(new Movie("Scarface", Movie.Genre.Regular), 3));
return result;
}
public static Customer CustomerWithOneNewRelease(string name)
{
var result = CustomerWithNoRentals(name);
result.AddRental(new Rental(new Movie("Godfather 4", Movie.Genre.NewRelease), 3));
return result;
}
public static Customer CustomerWithNoRentals(string name)
{
return new Customer(name);
}
}
public class Customer
{
private readonly string _name;
private readonly List<Rental> _rentals = new List<Rental>();
public Customer(string name)
{
_name = name;
}
public override string ToString()
{
return GetName();
}
public string GetName()
{
return _name;
}
public List<Rental> GetRentals()
{
return _rentals;
}
public void AddRental(Rental rental)
{
_rentals.Add(rental);
}
public string Statement()
{
var result = "Rental record for " + GetName() + "\r\n";
foreach (var rental in _rentals) result += "\t" + rental.GetLineItem() + "\r\n";
result += "Amount owed is " + GetTotalCharge() + "\r\n" + "You earned " + GetTotalPoints() +
" frequent renter points";
return result;
}
public string HtmlStatement()
{
var result = "<h1>Rental record for <em>" + GetName() + "</em></h1>\r\n";
foreach (var rental in _rentals) result += "<p>" + rental.GetLineItem() + "</p>\r\n";
result += "<p>Amount owed is <em>" + GetTotalCharge() + "</em></p>\r\n" + "<p>You earned <em>" +
GetTotalPoints() +
" frequent renter points</em></p>";
return result;
}
public double GetTotalCharge()
{
return _rentals.Sum(rental => rental.GetCharge());
}
public int GetTotalPoints()
{
return _rentals.Sum(rental => rental.GetPoints());
}
}
public class Rental
{
private readonly int _daysRented;
private readonly Movie _movie;
public Rental(Movie movie, int daysRented)
{
_movie = movie;
_daysRented = daysRented;
}
public Movie GetMovie()
{
return _movie;
}
public int GetDaysRented()
{
return _daysRented;
}
public double GetCharge()
{
return _movie.GetCharge(_daysRented);
}
public virtual int GetPoints()
{
return _movie.GetPoints(_daysRented);
}
public string GetLineItem()
{
return _movie.GetTitle() + "\t" + GetCharge();
}
}
public class Movie
{
public enum Genre
{
Regular,
NewRelease,
Children,
Unknown
}
private readonly string _title;
private Price _price;
public Movie(
string title, Genre priceCode)
{
_title = title;
SetPriceCode(priceCode);
}
public string GetTitle()
{
return _title;
}
private void SetPriceCode(Genre priceCode)
{
switch (priceCode)
{
case Genre.Children:
_price = new ChildrensPrice();
break;
case Genre.NewRelease:
_price = new NewReleasePrice();
break;
case Genre.Regular:
_price = new RegularPrice();
break;
default:
throw new ArgumentException("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
{
public abstract double GetCharge(int daysRented);
public virtual int GetPoints(int daysRented)
{
return 1;
}
}
public class ChildrensPrice : Price
{
public override double GetCharge(int daysRented)
{
var amount = 1.5;
if (daysRented > 3) amount += (daysRented - 3)*1.5;
return amount;
}
}
public class RegularPrice : Price
{
public override double GetCharge(int daysRented)
{
double amount = 2;
if (daysRented > 2) amount += (daysRented - 2)*1.5;
return amount;
}
}
public class NewReleasePrice : Price
{
public override double GetCharge(int daysRented)
{
return daysRented*3;
}
public override int GetPoints(int daysRented)
{
if (
daysRented > 1) return 2;
return 1;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment