Reputation: 41
I have a class
public class MockSampleUser {
private Address address = null;
public MockSampleUser(){
address = new Address();
}
public String getAddress(){
return address.getAddress();
}
class Address {
public String getAddress(){
return "Address";
}
}
}
Unit Test:
import static org.junit.Assert.*;
import org.junit.Test;
import static org.mockito.Mockito.*;
public class MockSampleUserTest {
@Test
public void MockSampleUser(){
MockSampleUser.Address address = mock(MockSampleUser.Address.class);
MockSampleUser mockSampleUser = spy(MockSampleUser.class);
when(address.getAddress()).thenReturn("New Address");
String add = mockSampleUser.getAddress();
assertEquals("New Address", add);
add = mockSampleUser.getAddress();
assertEquals("Address", add);
}
}
I want to write a test, when I call getAddress of class MockSampleUser when it will return "New Address". I want to write a test, when I call getAddress of class MockSampleUser when it will return "New Address".
Upvotes: 1
Views: 1546
Reputation: 131466
Mocking is designed to mock dependencies of the object under test, not to mock implementation details.
Actually address
is not a dependency that the client can set, so you don't have a way to mock it with Mockito.
What you should do is overloading the constructor/change the actual constructor to accept a Address
parameter or providing a setter for this field if the dependency is mutable.
For example with constructors :
public MockSampleUser(){
address = new Address();
}
public MockSampleUser(Address){
this.address = address;
}
For example with setter :
public void setAddress(Address){
this.address = address;
}
Note that about your unit test, you want that getAddress()
return distinct things as you invoke it multiple time :
String add = mockSampleUser.getAddress();
assertEquals("New Address", add);
add = mockSampleUser.getAddress();
assertEquals("Address", add);
It makes no sense as it references the same object and that its state was not changed between the two assertions.
Your test should rather look like (spy is helpless here and it is right for most of cases) if you don't allow the address dependency to be mutable :
@Test
public void MockSampleUser(){
MockSampleUser.Address address = mock(MockSampleUser.Address.class);
MockSampleUser mockSampleUser = new MockSampleUser(address);
when(address.getAddress()).thenReturn("New Address");
String add = mockSampleUser.getAddress();
assertEquals("New Address", add);
// or better, use the address object itself as expected
assertEquals(address.getAddress(), add);
}
If you allow the address dependency to be mutable, setter should be favored and there you can assert the before/after state of the object under test:
@Test
public void MockSampleUser(){
MockSampleUser mockSampleUser = new MockSampleUser();
// before setting the address
assertEquals("Address", mockSampleUser.getAddress());
// after setting the address
MockSampleUser.Address address = mock(MockSampleUser.Address.class);
mockSampleUser.setAddress(address);
when(address.getAddress()).thenReturn("New Address");
String add = mockSampleUser.getAddress();
assertEquals("New Address", add);
// or better, use the address object itself as expected
assertEquals(address.getAddress(), add);
}
Upvotes: 1