我知道关于模拟和测试有很多问题,但是我发现没有什么问题可以完美地帮助我,因此我仍然在理解以下方面存在问题:
如果我弄错了,请纠正我,但是据我所知,单元测试用于隔离测试一个特定类的业务逻辑,并且如果有外部需要的任何对象,它们将被模拟.
因此,例如,如果我有一个简单城市公民的管理系统,该系统将公民添加到列表中并按其姓名返回公民(假设:公民仅包含一些基本个人信息),如下所示:
public class ProcessClass {
ArrayList citizenList = new ArrayList();
public void addCitizen(Citizen citizen) {
citizenList.add(citizen);
}
public Citizen getByName(String name) {
for (Citizen c : citizenList) {
if (c.getName().equals(name)) {
return c;
}
}
return null;
}
}
如果现在我要对ProcessClass进行单元测试,是否将Citizen视为必须模拟的外部功能,还是仅出于测试目的而创建Citizen?
如果它们是模拟的,由于模拟对象不包含参数,我将如何测试该方法以按其名称获取对象?
解决方法:
If they are mocked, how would I test the method to get the object by its name, since the mock object is not containing the parameters?
您可以使用模仿程序模拟对getName的调用,例如:
Citizen citizen = mock(Citizen.class);
when(citizen.getName()).thenReturn("Bob");
这是您的方法测试的示例
ProcessClass processClass = new ProcessClass();
Citizen citizen1 = mock(Citizen.class);
Citizen citizen2 = mock(Citizen.class);
Citizen citizen3 = mock(Citizen.class);
@Test
public void getByName_shouldReturnCorrectCitizen_whenPresentInList() {
when(citizen1.getName()).thenReturn("Bob");
when(citizen2.getName()).thenReturn("Alice");
when(citizen3.getName()).thenReturn("John");
processClass.addCitizen(citizen1);
processClass.addCitizen(citizen2);
processClass.addCitizen(citizen3);
Assert.assertEquals(citizen2, processClass.getByName("Alice"));
}
@Test
public void getByName_shouldReturnNull_whenNotPresentInList() {
when(citizen1.getName()).thenReturn("Bob");
processClass.addCitizen(citizen1);
Assert.assertNull(processClass.getByName("Ben"));
}
注意:
我建议嘲笑.假设您编写了100个测试,以这种方式实例化一个Citizen类
Citizen c = new Citizen();
几个月后,您的构造函数更改为接受一个参数,该参数本身是一个对象,例如City类.现在,您必须返回并更改所有这些测试并编写:
City city = new City("Paris");
Citizen c = new Citizen(city);
如果您从一开始就嘲笑《公民》,则无需这样做.
现在,因为它是POJO,并且其getName方法的构造函数可能不会更改,所以不应该进行模拟.
标签:java,unit-testing
来源: https://codeday.me/bug/20191011/1889226.html