我正在学习有关单元测试的知识,我遇到了问题,以对测试案例进行最终检查是否正确。通常,我尝试创建一个验证,例如通过assertEquals()
。但是,当不可能这样测试时,建议做什么?
我有这样的课程:
public class Landlord {
private Map<String, ChannelHandlerContext> currentOccupier;
private static Landlord instance;
public Landlord() {
currentOccupier = new HashMap<>();
}
public static Landlord getInstance {
//return instance
}
public void add(Occupier occupier){
currentOccupier.put("test", occupier.getChannelHandlerContext());
}
}
现在我尝试测试这样的方法:
public class LandlordTest {
private Landlord landlord;
@Mock
private Occupier occupier;
@Mock
private ChannelHandlerContext channelHandlerContext;
@BeforeEach
void setUp() {
occupier = mock(Occupier.class);
channelHandlerContext = mock(ChannelHandlerContext.class);
landlord = Landlord.getInstance();
when(occupier.getChannelHandlerContext()).thenReturn(channelHandlerContext);
}
public void add(Occupier occupier){
addedOccupier.put(occupier.getChannelHandlerContext());
//adding succeded
}
}
也许在这个简短的示例中不需要测试它,但是有没有办法验证添加方法成功?通常,在这种情况下,我会尝试类似:assertEquals(currentOccupier.size(), 1)
,但是在这里我无法访问该实例的哈希图。有其他方法可以验证添加它的正确行为吗?
此assertEquals(currentOccupier.size(), 1)
确实不够。
您要断言该地图包含您在地图中添加的条目。
该断言太浅了:它没有检查输入键的值和值的值。
您应该做类似的事情:
ChannelHandlerContext actualContext = landLord.get("test");
assertSame(addedContext, actualContext);
// or assertEquals if the instances may differ because you do some defensive copy in add()
还请注意,您在这里嘲笑一些不需要模拟的事情:occupier
和channelHandlerContext
成为模型的一部分。您应该能够在测试框架中提供它们的"正常"实例。
在这里,您有两种方法可以执行:
1(在同类中添加公共方法进行测试以找到ChannelHandlerContext
:
public ChannelHandlerContext get(String name){
currentOccupier.get(name);
}
这样做如果提供此访问是可以接受的。
如果您无法添加公共方法,请添加软件包级别方法,因为这不会成为暴露的API的一部分。
2(使用反射API(本质上是Class.getDeclaredField(String)
和Field.get()
(从测试的实例中检索地图实例,然后断言它包含"测试"键的预期ChannelHandlerContext
实例。