java - 如何在构造函数中模拟实例?
问题描述
我有一堂课
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 时它会返回“新地址”。我想写一个测试,当我调用 MockSampleUser 类的 getAddress 时它会返回“新地址”。
解决方案
模拟旨在模拟被测对象的依赖关系,而不是模拟实现细节。
实际上address
不是客户端可以设置的依赖项,因此您无法使用 Mockito 模拟它。
如果依赖项是可变的,您应该做的是重载构造函数/更改实际构造函数以接受Address
参数或为此字段提供设置器。
例如构造函数:
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,并且您可以在其中断言被测对象的之前/之后状态:
@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);
}
推荐阅读
- c# - C# 随机 if 语句和标签追加
- directx - 是否有 Dx11-Dx12 方法来支持包含 SV_COVERAGE 的几何着色器
- sql-server - 如何在我的连接字符串中使用 SQL Server 应用程序角色
- vue.js - 使用 Vue2Leaflet 重新排序图层
- firebase - PhoneCredential 必须是有效的电话凭据
- javascript - 更改 Vue 数据对象
- java - 多循环的大 O
- sustainsys-saml2 - 在 SSL 卸载后使用 Sustainsys.saml2
- r - 解析格式化程序字符串
- android - 更改微调器下拉项文本颜色和文本大小