我有一个班级
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";
}
}
}
单元测试:
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);
}
}
我想写一个测试,当我调用类MockSampleUser的getAddress时它将返回" New Address"。 我想写一个测试,当我调用类MockSampleUser的getAddress时它将返回"新地址"。
答案 0 :(得分:1)
Mocking旨在模拟被测对象的依赖关系,而不是模拟实现细节
实际上address
不是客户可以设置的依赖项,因此您无法通过Mockito模拟它。
您应该做的是重载构造函数/更改实际构造函数以接受Address
参数,或者如果依赖项是可变的,则为此字段提供setter。
例如,使用构造函数:
public MockSampleUser(){
address = new Address();
}
public MockSampleUser(Address){
this.address = address;
}
例如使用setter:
public void setAddress(Address){
this.address = address;
}
请注意,关于您的单元测试,您希望getAddress()
在多次调用时返回不同的内容:
String add = mockSampleUser.getAddress();
assertEquals("New Address", add);
add = mockSampleUser.getAddress();
assertEquals("Address", add);
它没有意义,因为它引用了同一个对象,并且它的状态在两个断言之间没有改变。
如果你不允许地址依赖是可变的,那么你的测试应该看起来像是(间谍在这里是无助的,大多数情况下都是正确的):
@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);
}
如果你允许地址依赖是可变的,那么应该优先使用setter,并且你可以断言被测对象的before / after状态:
@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);
}