Over a million developers have joined DZone.

Legacy Code To Testable Code #2: Extract Method

· DevOps Zone

Discover how to optimize your DevOps workflows with our cloud-based automated testing infrastructure, brought to you in partnership with Sauce Labs

This post is part of the “Legacy Code to Testable Code” series. In the series we’ll talk about making refactoring steps before writing tests for legacy code, and how they make our life easier.

As with renaming, extracting a method helps us understand the code better. If you find it easy to name the method, it makes sense. Otherwise, you just enclosed code that does a lot of things. It can be useful sometimes, although not as extracting small methods that make sense.

Extracting a method also introduces a seam. This method can now be mocked, and can now affect the code as it being tested. One of the tricks when not using power-tools is wrapping a static method with an instance method. 

In our Person class, we have the GetZipCode method: 

public class Person { 
    String street; 

    public String getZipCode() { 
        Directory directory = Directory.getInstance(); 
        return directory.getZipCodeFromStreet(street); 
    } 
} 

The Directory.getInstance() method is static. If we extract it to a getDirectory method (in thePerson class) and make this method accessible, we now can mock it.

public class Person { 
    String street; 
    
    public String getZipCode() { 
        Directory directory = getDirectory(); 
        return directory.getZipCodeFromStreet(street); 
    }
    
    protected Directory getDirectory() { 
        return Directory.getInstance(); 
    } 
}

While it's now very easy to mock the getDirectory method using Mockito, it was also easy to mock the Directory.getInstance if we used PowerMockito. Is there an additional reason to introduce a new method? 

If it’s just for the sake of testing - there's no need to do the extraction. Sometimes, however mocking things with power-tools is not easy. Problems appearing in static constructors may require more handling on the test side. It may be easier to wrap in a separate method. 

There are times when extracting helps us regardless of the mocking tool. We can use method extraction to simplify the test, even before we've written it. It's simpler and safer to mock one method, rather than 3 calls.

If our getZipCode method looked like this: 

public String getZipCode() { 
    Address address = new Address(); 
    address.setStreet(street); 
    address.setCountry(country); 
    address.setState(state); 
    address.setCity(city); 
    
    Directory directory = Directory.getInstance(address); 
    return directory.GetZipCode(); 

Even with power-tools, faking the Address instance and setting the rest of the behavior settings just for retrieving the directory is quite a lot of work, which means a longer test with a long setup. If we extract a getDirectoryFromAddress method:

public String getZipCode() { 
    Directory directory = getDirectoryFromAddress(); 
    return directory.GetZipCode(); 
} 

We get more readable code, and we'll need to mock only one line.

While extracting has its up side, making a method a seam comes with the baggage. If the method is private, and we use power tools to mock it, coupling between test and code is increased. If we make it public, someone can call it. If it's protected, a derived class can call it. Changes for testability is a change of design, for better or worse.

Up next: Creating accessors.


Download “The DevOps Journey - From Waterfall to Continuous Delivery” to learn learn about the importance of integrating automated testing into the DevOps workflow, brought to you in partnership with Sauce Labs.

Topics:

Published at DZone with permission of Gil Zilberfeld, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}