Skip to content

Instantly share code, notes, and snippets.

@TheSecretSquad
Last active August 24, 2016 05:09
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TheSecretSquad/4ce96aadc80debbcbb85655019f32f89 to your computer and use it in GitHub Desktop.
Save TheSecretSquad/4ce96aadc80debbcbb85655019f32f89 to your computer and use it in GitHub Desktop.
// The first thing I did was generalize the "orders have free shipping to Australia" concept
// to "orders adjust their shipping charges in some way".
// I wouldn't want Order to get cluttered with lots of shipping rules.
// Instead of doing this in constructor, it could instead have a method like
// order.adjustShipping(shippingAdjustments).
@Test
public void whenCreatingAnOrder_AdjustsShippingCharges() {
ShippingAdjustments mockedShippingAdjustments = mock(ShippingAdjustments.class);
Country mockedCountry = mock(Country.class);
Order order = new Order(mockedCountry, mockedShippingAdjustments, other, parameters);
verify(mockedShippingAdjustments).adjustForCountry(order, mockedCountry);
}
public class Order {
private Country country;
public Order(Country country, ShippingAdjustments shippingAdjustments, Other other, Parameters parameters) {
this.country = country;
shippingAdjustments.adjustForCountry(this, this.country);
}
}
// I then tested the ShippingAdjustments concept as follows...
@Test
public void whenEvaluatingShippingAdjustments_AppliesAllAdjustments() {
ShippingAdjustment mockAdjustment1 = mock(ShippingAdjustment.class);
ShippingAdjustment mockAdjustment2 = mock(ShippingAdjustment.class);
ShippingAdjustment mockAdjustment3 = mock(ShippingAdjustment.class);
Shippable mockShippable = mock(Shippable.class);
Country mockCountry = mock(Country.class);
ShippingAdjustments shippingAdjustments = new ShippingAdjustments(mockAdjustment1, mockAdjustment2, mockAdjustment3);
shippingAdjustments.adjustForCountry(shippable, mockCountry);
verify(mockAdjustment1).adjustForCountry(mockShippable, mockCountry);
verify(mockAdjustment2).adjustForCountry(mockShippable, mockCountry);
verify(mockAdjustment3).adjustForCountry(mockShippable, mockCountry);
}
// This eludes to the Shippable and ShippingAdjustment interface
public interface Shippable {
}
public interface ShippingAdjustment {
void adjustForCountry(Shippable shippable, Country country);
}
public class ShippingAdjustments {
private List<ShippingAdjustment> shippingAdjustments;
public ShippingAdjustments(ShippingAdjustment ... shippingAdjustments) {
this.shippingAdjustments = Arrays.asList(shippingAdjustments);
}
public void adjustForCountry(Shippable shippable, Country country) {
for(ShippingAdjustment adjustment : shippingAdjustments) {
adjustment.adjustForCountry(shippable, country);
}
}
}
// Then testing the shipping adjustment in question, we can also flesh out
// the behavior for Shippable
@Test
public void free_shipping_applies_within_australia() {
Shippable mockShippable = mock(Shippable.class);
FreeShippingAdjustment freeShippingAdjustment = new FreeShippingAdjustment();
freeShippingAdjustment.adjustForCountry(mockShippable, new Country("Australia"));
verify(mockShippable).freeShipping();
}
// Would also have a test that verifies it does not apply the adjustment when the country does not match
// This gives a new method for Shippable
public interface Shippable {
void freeShipping();
}
// We can make Order implement Shippable and update the implementation
// along with a test for it
public class Order implements Shippable {
private Country country;
private boolean freeShipping;
public Order(Country country, ShippingAdjustments shippingAdjustments, Other other, Parameters parameters) {
this.country = country;
this.freeShipping = false;
shippingAdjustments.adjust(this);
}
public void freeShipping() {
this.freeShipping = true;
}
}
public class FreeShippingAdjustment implements ShippingAdjustment {
private Country appliesForCountry;
public FreeShippingAdjustment() {
this.appliesForCountry = new Country("Australia");
}
public void adjustForCountry(Shippable shippable, Country country) {
if(appliesForCountry.equals(country)) {
shippable.freeShipping();
}
}
}
public class FreeShippingAdjustment implements ShippingAdjustment {
private Country appliesForCountry;
public FreeShippingAdjustment() {
this.appliesForCountry = new Country("Australia");
}
public void adjustForCountry(Shippable shippable, Country country) {
if(appliesForCountry.equals(country)) {
shippable.freeShipping();
}
}
}
// Tests
@Test
public void free_shipping_applies_within_australia() {
Shippable mockShippable = mock(Shippable.class);
FreeShippingAdjustment freeShippingAdjustment = new FreeShippingAdjustment();
freeShippingAdjustment.adjustForCountry(mockShippable, new Country("Australia"));
verify(mockShippable).freeShipping();
}
public class Order implements Shippable {
private Country country;
private boolean freeShipping;
public Order(Country country, ShippingAdjustments shippingAdjustments, Other other, Parameters parameters) {
this.country = country;
this.freeShipping = false;
shippingAdjustments.adjustForCountry(this, this.country);
}
public void freeShipping() {
this.freeShipping = true;
}
}
// Tests
@Test
public void whenCreatingAnOrder_AdjustsShippingCharges() {
ShippingAdjustments mockedShippingAdjustments = mock(ShippingAdjustments.class);
Country mockedCountry = mock(Country.class);
Order order = new Order(mockedCountry, mockedShippingAdjustments, other, parameters);
verify(mockedShippingAdjustments).adjustForCountry(order, mockedCountry);
}
public interface ShippingAdjustment {
void adjustForCountry(Shippable shippable, Country country);
}
public class ShippingAdjustments {
private List<ShippingAdjustment> shippingAdjustments;
public ShippingAdjustments(ShippingAdjustment ... shippingAdjustments) {
this.shippingAdjustments = Arrays.asList(shippingAdjustments);
}
public void adjustForCountry(Shippable shippable, Country country) {
for(ShippingAdjustment adjustment : shippingAdjustments) {
adjustment.adjustForCountry(shippable, country);
}
}
}
// Tests
@Test
public void whenEvaluatingShippingAdjustments_AppliesAllAdjustments() {
ShippingAdjustment mockAdjustment1 = mock(ShippingAdjustment.class);
ShippingAdjustment mockAdjustment2 = mock(ShippingAdjustment.class);
ShippingAdjustment mockAdjustment3 = mock(ShippingAdjustment.class);
Shippable mockShippable = mock(Shippable.class);
Country mockCountry = mock(Country.class);
ShippingAdjustments shippingAdjustments = new ShippingAdjustments(mockAdjustment1, mockAdjustment2, mockAdjustment3);
shippingAdjustments.adjustForCountry(shippable);
verify(mockAdjustment1).adjustForCountry(mockShippable, mockCountry);
verify(mockAdjustment2).adjustForCountry(mockShippable, mockCountry);
verify(mockAdjustment3).adjustForCountry(mockShippable, mockCountry);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment