i using mockito write unit tests application tested integration testing need develop unit tests.
this code testing :
public class testresourceb { @mock resourceb b; @mock resourcec c; @before public void setup() { mockitoannotations.initmocks(this); testobjects.initializeobjects(); } @test public void testmethodresourcea() { when(b.callfunca()).thencallrealmethod(); when(b.callfuncb()).thenreturn(testobjects.mockedlista); when(b.callfuncc((b)anyvararg())).thencallrealmethod(); when(c.callfuncb()).thenreturn(testobjects.mockedlistb); when(c.callfunca()).thencallrealmethod string output = b.callfunca(); } }
this class resourceb
public class resourceb { resourcec c = new resourcec(); public string callfunca(){ /*calling callfuncb , doing other stuff*/ string test = callfuncc(arg1); } public list<a> callfuncb() { /*returns mocked list a*/ } public string callfuncc(b arg1) { string test2 = c.callfunca(); // crashes here /*doing other stuff*/ } }
this class resourcec
public class resourcec { public string callfunca() { /*calling callfuncb , doing other stuff*/ return teststring; } public list<b> callfuncb() { /*return list*/ } }
the problem have in method callfuncc in class resourceb when line
string test2 = c.callfunca();
is called nullpointerexception
any idea why happening ?
there several issues in code, first 1 being mocking class want test, doing test mock of resourceb
or you'll have stub code , force chosen method call real code (thencallrealmethod
). main idea never mock class testing.
that why have npe, because mock don't need internal fields instance. should'nt need to.
here's correct way, there might variations 1 straightforward. you'd want test interactions between resourceb
, resourcec
, unit test of resourceb
you'd want mock resourcec
. thing mocks per instance have pass mocked 1 resourceb
.
it can injected via constructor injection, need modify resourceb
:
public class resourceb { resourcec c; public resourceb() { c = new resourcec(); } // normal behavior @visiblefortesting // guava annotation (in, order expalain why there constructor) resourceb(resourcec c_override) { c = c_override; } // constructor test, note package visibility // ... }
and in test you'll write way :
public class testresourceb { resourceb tested_b; @mock resourcec mocked_c; @before public void init_tested_and_mocks() { mockitoannotations.initmocks(this); tested_b = new resourceb(mocked_) } @test public void ensure_result_from_resourcec_is_returned() { // given when(mocked_c.callfunca()).thenreturn("result should returned"); // when string output = tested_b.callfunca(); // assertthat(output).isequalto("result should returned"); } }
by way here's few things add :
- as using junit 4.x, i'm using more meaningful/descriptive method names.
- i'm using behavior driven development keywords (given, when, then) drive test scenario.
- also use assertj lib write meaningful assertions.
Comments
Post a Comment