如何编写JUNIT测试案例以进行比较代码覆盖
我有一个使用比较器界面的分类机制,如下所示:
public class SortByEmployeeIdByDesc implements Comparator<Employee> {
public int compare(Employee a, Employee b)
{
return b.getEmpId().compareTo(a.getEmpId());
}
}
这是我的员工类:
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
@Getter
private String empId;
private String empName;
private Date createdTime;
@Getter
private Date lastUpdatedTime;
}
我已经为上述比较器书写了类似的测试用例:
@ExtendWith(MockitoExtension.class)
public void EmployeeSortTest{
@Test
public void sortEmpDescloyeeTest() {
Employee emp1 = new Employee("abc", "test", "2020-10-10", "2010-10-10");
Employee emp2 = new Employee("xyz", "test2", "2022-03-04", "2022-03-04");
List<Employee> sortEmp = new ArrayList<>();
sortEmp.add(emp1);
sortEmp.add(emp2);
Collections.sort(sortEmp, new SortByEmployeeIdByDesc());
assertEquals(emp1, sortEmp.get(1));
}
}
上面的测试案例成功运行,但是当我在Sonar中检查时,它并不能涵盖代码。是否有更好的JUNIT测试方法,以便覆盖范围至少增加到90%?
I have a Sorting mechanism using Comparator interface like below:
public class SortByEmployeeIdByDesc implements Comparator<Employee> {
public int compare(Employee a, Employee b)
{
return b.getEmpId().compareTo(a.getEmpId());
}
}
Here is my Employee class:
@Builder
@AllArgsConstructor
@NoArgsConstructor
public class Employee {
@Getter
private String empId;
private String empName;
private Date createdTime;
@Getter
private Date lastUpdatedTime;
}
I have written test cases like below for the above comparator:
@ExtendWith(MockitoExtension.class)
public void EmployeeSortTest{
@Test
public void sortEmpDescloyeeTest() {
Employee emp1 = new Employee("abc", "test", "2020-10-10", "2010-10-10");
Employee emp2 = new Employee("xyz", "test2", "2022-03-04", "2022-03-04");
List<Employee> sortEmp = new ArrayList<>();
sortEmp.add(emp1);
sortEmp.add(emp2);
Collections.sort(sortEmp, new SortByEmployeeIdByDesc());
assertEquals(emp1, sortEmp.get(1));
}
}
The above test case is running successfully, but when I am checking in Sonar, it's not covering the code. Is there a better Junit test approach so that the coverage increases to at least 90%?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我已经对语言版本和依赖项做出了一些假设,并运行您的代码:
您的
new Employee(...)
构造仪不起作用,因为您的@allargsconstructor
期望date
对象而不是String
。假设您使用的是Java8+,则应使用
localdate
而不是date
。代码覆盖范围得出以下结果。
员工Java:50%
未覆盖的行:
sortbyeMployeeIdByDesc:100%
要涵盖新行,您应该考虑更改测试类,如下(例如):
因为您仅声明
@getter
其中两个字段,您无法在BuilderTest
中测试其他字段。如果要比较所有字段可以执行以下操作:
添加
@equalsandhashcode
雇员上的注释 -更改
builderTest
代码,如下所示 -这两种方法(使用或不使用
@equalsandhashcode
注释)产生100%代码覆盖范围。请记住,除非您在守望者和二传手中具有逻辑,否则覆盖它们通常被认为是微不足道的,因为您本质上是在测试Java分配,这可能会假定工作。I've made some assumptions about language version and dependencies and run your code:
Your
new Employee(...)
constructors weren't working because your@AllArgsConstructor
is expecting aDate
object not aString
.Assuming you're using Java8+, you should use
LocalDate
instead ofDate
.Code coverage yields the following results.
Employee.java: 50%
Uncovered lines:
SortByEmployeeIdByDesc: 100%
To cover the new lines, you should consider changing your test class as follows (for example):
Because you've only declared
@Getter
on two of the fields, you can't test the others in thebuilderTest
.If you want to compare all the fields you could do the following:
Add the
@EqualsAndHashCode
annotation on Employee -Change the
builderTest
code as follows -Both approaches (with or without the
@EqualsAndHashCode
annotation) yield 100% code coverage. Bear in mind that unless you have logic in your getters and setters, covering them is usually considered trivial because you are essentially testing Java assignment, which one may assume to work.要测试比较器,第一个想法可能是将一些项目添加到列表中,对列表进行排序,然后确保对项目进行正确排序。
但是,这种方法的缺点很差:排序列表会尽可能少地比较,这与您要完成的工作完全相反。另外,根据排序算法,您无法确定完全比较了哪些组合。
我曾经写过
comparatterter
,该列出了元素列表,然后将每个元素与每个元素进行比较。它还确保比较器是反射性,反对称性和及时性的。当我谷歌搜索comparatortester时,我发现 firebase的实现,它与我自己的实现非常相似,因为它使用了完全相同的想法。这就是您应该遵循的方法。
在琐碎的用例中,您甚至不需要编写自己的比较器类,这是Java 8之前的一件事。如今,通过单个属性进行排序变成了一个单元:
To test a comparator, the first idea may be to add a few items to a list, sort the list and then ensure that the items have been sorted correctly.
This approach has a terrible downside though: sorting a list performs as few comparisons as possible, which is exactly the opposite of what you are trying to accomplish. Plus, depending on the sorting algorithm, you cannot be sure which combinations have been compared at all.
I once wrote a
ComparatorTester
that took a list of elements and then compared each element to each element. It also made sure that the comparator is reflexive, antisymmetrical and transitive.When I googled for ComparatorTester, I found an implementation by Firebase that felt remarkably similar to my own implementation, as it uses the exact same idea. That's the approach you should follow.
In your trivial use case, you don't even need to write your own comparator class, that's a thing from before Java 8. Nowadays, sorting by a single property becomes a one-liner:
comparator.compare(t o1,t o2)
javadoc state (添加了强调):因此,在最小上,您的测试需要涵盖上述三个条件:
我正在使用 assertj 在此示例中,强烈建议您在项目中使用它。
此外,您的员工ID是字符串。因此,您需要进行测试,以便它是
null
。然后,您将获得所需的覆盖范围。The
Comparator.compare(T o1, T o2)
javadoc states (emphasis added):Therefore, at the minimum your test needs to cover the above three conditions:
I'm using AssertJ in this example and highly recommend using it in your projects.
In addition, your employee id is a String. So you need a test for when it's
null
. Then you will have the desired coverage.