How to refactor method?

How to refactor a method to make it easier to test

  • Below is a method that I'm having a hard time figuring out how to test using JUnit. This method is difficult to test because it depends on the results of other methods (e.g. getClosestDcoumentCode). Based on my reading of JUnit, this suggests I should refactor the method. But how? And if refactoring is not necessary, how do you test a method that depends on other methods? Thank you, Elliott private static String findPrincipal(List<DocumentKey> documentkeys_) { Hashtable<String, Integer> codecounts = new Hashtable<String, Integer>(); for (DocumentKey document : documentkeys_) { int x = 0; String closestCode = getClosestDocumentCode(document.candidates); if (closestCode == null) continue; int thecount = 0; if (codecounts.containsKey(closestCode)) thecount = codecounts.get(closestCode); if (document.hasKey) thecount += 2; else thecount++; codecounts.put(closestCode, new Integer(thecount)); x++; } String closestCode = getClosestCode(codecounts); return closestCode; }

  • Answer:

    It sounds to me like getClosestCode and getClosestDocumentCode belong to a different set of responsibilities than the findPrincipal method. So you'll want to begin by separating these into two different classes. Create an interface for each class to implement. The class that implements the findPrincipal method can then rely on the other interface as a constructor argument, like this: public class PrincipalFinderImpl implements PrincipalFinder { private CodeFinder codeFinder; public PrincipalFinderImpl(CodeFinder codeFinder) { this.codeFinder = codeFinder; } public String findPrincipal(List<DocumentKey> documentkeys_) { Hashtable<String, Integer> codecounts = new Hashtable<String, Integer>(); for (DocumentKey document : documentkeys_) { int x = 0; String closestCode = codeFinder.getClosestDocumentCode(document.candidates); if (closestCode == null) continue; int thecount = 0; if (codecounts.containsKey(closestCode)) thecount = codecounts.get(closestCode); if (document.hasKey) thecount += 2; else thecount++; codecounts.put(closestCode, new Integer(thecount)); x++; } String closestCode = codeFinder.getClosestCode(codecounts); return closestCode; } } Now it should be easy to create another class the implements the CodeFinder interface, either manually or using a Mocking framework. You can then control the results of each call to getClosestCode and getClosestDocumentCode, and ensure that each of these methods gets called with exactly the arguments you expect it to be called with.

Elliott at Stack Overflow Visit the source

Was this solution helpful to you?

Other answers

Well, first of all, I wonder if the method really needs to be static, and what that class is doing. It looks like it might be a GOD class, or at the very least it's violating the single responsibility principle. What does getClosestCode do? If it was a class, you could inject it with a stub in your tests into the test class. EasyMock will let you mock the method response, but I'm not sure how you mock static methods. In general, you probably need to Extract long functions into classes Make functionality non-static Maintain the single responsibility principal

Stefan Kendall

I don't read the method deeply. But if a private method needs to test, it indicates something wrong with your design. At least http://stackoverflow.com/questions/440786/junit-java-testing-non-public-methods/440803#440803.

卢声远 Shengyuan Lu

There is a chapter on stub calls on http://www.manning.com/tahchiev/, i recommend you have a look at that if you think your existing codes are not written to test-driven development standards.

Chin Boon

Just Added Q & A:

Find solution

For every problem there is a solution! Proved by Solucija.

  • Got an issue and looking for advice?

  • Ask Solucija to search every corner of the Web for help.

  • Get workable solutions and helpful tips in a moment.

Just ask Solucija about an issue you face and immediately get a list of ready solutions, answers and tips from other Internet users. We always provide the most suitable and complete answer to your question at the top, along with a few good alternatives below.