Last active
August 24, 2016 05:09
-
-
Save TheSecretSquad/4ce96aadc80debbcbb85655019f32f89 to your computer and use it in GitHub Desktop.
Rewrite of example from https://dzone.com/articles/stop-mocking-start-newing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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(); | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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(); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public interface ShippingAdjustment { | |
void adjustForCountry(Shippable shippable, Country country); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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