Breaking dependencies

After having created a test that guarantees the expected behavior does not change, we will break the hardcoded dependency between BirthdayGreetingService and EmailMessageSender. For this, we will use a technique called extract and override call, which is first explained in Michael Feathers' book:

public class BirthdayGreetingService { 
 
  public BirthdayGreetingService() { 
    messageSender = getMessageSender(); 
  } 
 
  private MessageSender getMessageSender() { 
    return new EmailMessageSender(); 
  } 
 
[...] 

Execute the tests again and verify that the lonely test we previously created still is green. Additionally, we need to make this method protected or more open to be able to override it:

public class BirthdayGreetingService { 
 
  protected MessageSender getMessageSender() { 
    return new EmailMessageSender(); 
  } 
 
[...] 

Now that the method can be overridden, we create a fake service to replace the original instance of the service. Introducing fakes in code is a pattern that consists of creating an object that could replace an existing one, with the particularity that we can control its behavior. This way, we can inject some customized fakes to achieve what we need. More information is available at http://xunitpatterns.com/.

In this particular case, we should create a fake service that extends the original service. The next step is to override complicated methods in order to bypass irrelevant parts of code for testing purposes:

public class FakeBirthdayGreetingService 
extends BirthdayGreetingService { @Override protected MessageSender getMessageSender() { return new EmailMessageSender(); } }

Now we can use the fake, instead of the BirthdayGreetingService class:

public class EndToEndTest { 
 
  @Test 
  public void email_an_employee() { 
    final StringBuilder systemOutput = 
      injectSystemOutput(); 
    final Employee john = new Employee( 
       new Email("[email protected]")); 
 
    new FakeBirthdayGreetingService().greet(john); 
 
    assertThat(systemOutput.toString(), 
      equalTo("Sent email to " 
        + "'[email protected]' with " 
        + "the body 'Greetings on  
        + "your birthday'
")); 
  } 

The test is still green.

We can now apply another dependency-breaking technique, parameterize constructor, explained in Feathers paper at https://archive.org/details/WorkingEffectivelyWithLegacyCode. The production code may look like this:

public class BirthdayGreetingService { 
 
  public BirthdayGreetingService(final MessageSender 
messageSender) { this.messageSender = messageSender; } [...] }

Test code that corresponds to this implementation may be as follows:

public class EndToEndTest { 
 
  @Test 
  public void email_an_employee() { 
    final StringBuilder systemOutput = 
      injectSystemOutput(); 
    final Employee john = new Employee( 
      new Email("[email protected]")); 
 
    new BirthdayGreetingService(new 
EmailMessageSender()).greet(john); assertThat(systemOutput.toString(), equalTo("Sent email to " + "'[email protected]' with " + "the body 'Greetings on " + "your birthday' ")); } [...]

We can also remove FakeBirthday, as it is no longer used.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.128.199.138