在为分析计算器编写单元时,我意识到为了测试一个简单的功能,我已经手动创建了带有测试值的存根pojo,这将花费更多的时间来编写实际的业务逻辑?例如,如果我想检查一个计算和( person.age ) / count (person)
的函数现在,在编写java junits时,我模拟了返回person对象集合的服务,然后手动创建了3个person对象,每个对象都有一些年龄。
现在,如果person类很大,就说30-40个字段。有没有一种简单的方法来创建这样的对象?像拉数据从db和创建对象通过解析从db采取的CSV文件的飞行?
我想知道推荐的方法是什么?
关于unittest最基本的一点是,它们应该很快。如果一个单元测试花费的时间太长,人们就会停止执行它。由于这个原因(以及单元测试无法控制的错误的危险,比如数据库关闭),我不建议将这些值存储在数据库中。
但是你的情况听起来好像你真的需要30-40个字段来填充,不是吗?为什么你们班需要所有这些?如果有,这些字段是有意义的还是可以用随机数据填充?或者每个人都有相同的数据,除了你想测试的东西?
就我个人而言,我不喜欢访问文件或类似的东西来测试与文件处理无关的东西,所以我会寻找一种方法来限制测试必须做的事情(测试也应该很容易,如果它非常长,没有人能理解它)。如果必须的话,我会选择文件而不是数据库(原因很简单,因为文件可以存储在测试资源中,并且至少比数据库的问题少)。但是,最好的方法可能不需要文件或数据库。
我建议将逻辑组中的40个字段分开,每组分别测试逻辑。这意味着:
- 创建pojo填充属于第一组的字段
- 测试逻辑
- 为第二组创建pojos填充字段
等等
最好是有子pojo,每个子pojo都有来自一个组的字段,分别独立地进行测试。例如,Person可以有一个Address实例,一个Work实例....
我强烈建议不要动态地从数据库中提取数据:这很容易使您的测试不确定(即,如果数据更改,可能会中断),并且测试本身中未检测到/未测试的错误可能会使您的平均测试无用。此外,如果您从数据库离线创建"代表性结果"(然后,例如,签入它们),您可能必须特别小心随机选择字段,并避免以可泄漏的方式保存敏感或个人信息。
编写测试可能比编写被测系统花费的时间要长,这并不奇怪,而且并不一定是有问题的指示——特别是对于关键任务的代码。也就是说,您通常可以用与优化代码相似的方法来优化测试。
取决于你的模型对象是否可变,你可能想要考虑一个测试助手库,它创建一个Person或PersonBuilder类,其中随机的起始值取自一个确定性种子。此时,您的测试可能看起来像这样:
@Test public void testMeanAge() {
// Each person will have a name like "iuwaqeiouzzsxdfv", and a
// randomized age from 18 to 80 (for instance), and so on
Person person1 = PersonBuilder.random().withAge(25).build();
Person person2 = PersonBuilder.random().withAge(28).build();
Person person3 = PersonBuilder.random().withAge(28).build();
when(yourService.getPeople())
.thenReturn(new Person[] { person1, person2, person3 });
assertEquals(27, yourPerson.getMeanAge());
}
创建测试构建器将会有些冗长,而且不是那么有趣,并且您需要对测试所关心的实际潜在值有一定的了解,但是使用类似这样的东西,您可以非常容易地创建一个假Person—这可能在您的代码库中的其他测试中会派上用场。