java - How should I unit-test a long function? -
if have long method of code gathers data 2 or 3 difference sources , returns result. how can refactor more unit-testable? method webservice , want make 1 call client code gather data.
i can refactor portions out smaller methods more testable. current method still calling 5 methods , remain less testable. assuming java programming language, there pattern making such code testable?
this common testing problem, , common solution come across separate sourcing of data code uses data using dependency injection. not supports testing, strategy when working external data sources (good segregation of responsibilities, isolates integration point, promotes code reuse being reasons this).
the changes need make go like:
- for each data source, create interface define how data source accessed, , factor out code returns data separate class implements this.
- dependency inject data source class containing 'long' function.
- for unit testing, inject mock implementation of each data source.
here code examples showing - note code merely illustrative of pattern, need more sensible names things. worth studying pattern , learning more dependency injection & mocking - 2 of powerful weapons in unit testers armory.
data sources
public interface datasourceone { public data getdata(); } public class datasourceoneimpl implements datasourceone { public data getdata() { ... return data; } } public interface datasourcetwo { public data getdata(); } public class datasourcetwoimpl implements datasourcetwo { public data getdata() { ... return data; } }
class long method
public class classwithlongmethod { private datasourceone datasourceone; private datasourcetwo datasourcetwo; public classwithlongmethod(datasourceone datasourceone, datasourcetwo datasourcetwo) { this.datasourceone = datasourceone; this.datasourcetwo = datasourcetwo; } public result longmethod() { somedata = datasourceone.getdata(); somemoredata = datasourcetwo.getdata(); ... return result; } }
unit test
import org.junit.test; import static org.mockito.mockito.mock; import static org.mockito.mockito.when; public class classwithlongmethodtest { @test public void testlongmethod() { // create mocked data sources return data required test datasourceone datasourceone = mock(datasourceone.class); when(datasourceone.getdata()).thenreturn(...); datasourcetwo datasourcetwo = mock(datasourcetwo.class); when(datasourcetwo.getdata()).thenreturn(...); // create object under test using mocked data sources classwithlongmethod sut = new classwithlongmethod(datasourceone, datasourcetwo); // can unit test long method in isolation it's dependencies result result = sut.longmethod(); // assertions on result ... } }
please forgive (and correct) syntactic mistakes, don't write java these days.
Comments
Post a Comment