Reputation: 1273
I have been practising Junit to write the test cases and came across Mockito with which I can mock the dependency objects. So I have written a sample code to test it's behaviour.
I have two classes Sample and Second.
Second class has a simple method which just returns a string which is passed as a parameter to this method
public class Second{
public String show(String y ){
return y
}
}
Now there is a Sample class where I called this show method inside Sample classe's method and returning the string.
public class Sample{
public String sampleMethod(){
Second s = new Second();
return s.show("This should not be displayed");
}
}
Now I'm testing the Sample class hence I have created a file naming SampleTest
public class SampleTest{
@Mock
Second s;
@InjectMocks
Sample s = new Sample();
@Before
public void setUp(){
MockitoAnnotations.initMocks(this);
when(s.show(any(String.class))).thenReturn("This should be displayed");
}
@Test
public void sampleMethodTest(){
assertEquals("This should be displayed", s.sampleMethod());
}
}
Now as the Second classes object is created and its method is being called inside the Sample method, I have Mocked the Second class and Injected the mocks into Sample.
Then inside the Before method I have written when and thenReturn statements which will be :
when show method is called inside the second object then I returned my desired outpput which is "This should be displayed"
But the output is not what I expected instead of calling the when and thenreturn statements, the real show method inside the Second object is called.
I'm not able to mock the object which is created the method.
How do I do that?
And I need to be done only with mockito not with powermockito
Upvotes: 1
Views: 13939
Reputation: 247571
Sample
is tightly coupled to Second
by creating it within the method under test.
Given the currently stated limitations,
And I need to be done only with mockito not with powermockito
Mockito will not be able to mock the Second
used within the Sample
.
If Sample
can be refactored to follow a more SOLID design like Explicit Dependency Principle via constructor injection.
public class Sample {
private final Second second;
public Sample(Second second) {
this.second = second;
}
public String sampleMethod(){
return s.show("This should not be displayed");
}
}
Then the dependency would be able to be mocked and injected into the subject class under test
public class SampleTest {
@Mock
Second second;
@InjectMocks
Sample sample; //second will be injected here
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void sampleMethodTest() {
//Arrange
String expected = "This should be displayed";
when(second.show(any(String.class))).thenReturn(expected);
//Act
String actual = sample.sampleMethod();
//Assert
assertEquals(expected, actual);
}
}
Note the changes to the test so that it behaves as expected when exercised.
If you can't refactor Sample
, powerMockito can mock the class initialization.
While powerMockito allows such things, it facilitates poor design choices and code smells like tight coupling, which makes the code difficult to maintain and to test in isolation.
Upvotes: 1