如何为 JUnit 测试测试 Comparator?
How to test Comparator for JUnit test?
我需要测试 compare() 方法,但我对如何测试感到困惑。我能看看怎么做吗?
public class MemberComparator implements Comparator<Member> {
private final String clientId;
public MemberComparator(String clientId) {
this.clientId = clientId;
}
@Override
public int compare(Member m1, Member m2) {
if (m1.getClientId().startsWith(clientId)) {
return m2.getClientId().startsWith(clientId) ? m1.getClientId().compareTo(m2.getClientId())
: -1;
} else {
return m2.getClientId().startsWith(clientId) ? 1
: m1.getClientId().compareTo(m2.getClientId());
}
}
}
到目前为止,这是我在测试中创建的。我怎样才能让它工作?假设我不更改 MemberComparator class.
的当前方法,我应该怎么做,因为这种方式不起作用
class MemberComparatorTest {
//private MemberComparator caseID_test;
//private final MemberComparator memberComparator = new MemberComparator("jake");
@Test
void testEqual() {
Member m1 = new Member();
Member m2 = new Member();
int result = memberComparator.compare(m1,m2);
//assertTrue("expected to be equal", result == 0);
}
}
写 Comparator
时需要回答两个问题:
- 是否满足
Comparator
接口的要求?
- 它能满足您的需求吗?
第一个相当难以编写测试;我认为最好使用“已知良好”模式编写一些东西,以帮助您从代码中推断出它的正确性。
在 Comparator
的情况下,“已知良好”模式是您从链接方法中看到的:
// This boolean comparison may be the wrong way round, I never remember which way is which. If so, reverse it.
Comparator.comparing(m -> m.getClientId().startsWith(clientId))
.thenComparing(Member::getClientId)
你比较第一件事,return如果它们不同;你比较第二件事,return 如果它们不同,等等
如果您使用的是 Java 8+,则可以使用上面的代码:这完全可以 Comparator
。如果您不能使用它(无论出于何种原因),您的 compare
方法可以重写为:
int compareSw = Boolean.compare(m1.getClientId().startsWith(clientId), m2.getClientId().startsWith(clientId));
if (compareSw != 0) {
return compareSw;
}
return m1.getClientId().compareTo(m2.getClientId());
因为这遵循“已知良好”模式,所以通过检查可以看出满足Comparator
接口的要求。
(当然,你必须小心思考“对我来说看起来不错!”,因为你可能会错过一些东西,例如使用 m1.getClientId()
两次而不是 m1.getClientId()
和 m2.getClientId()
。但是,通过对以下内容进行充分测试,可以发现这种缺陷。
那么这只是一个测试问题,以确保它你想要什么:也就是说,如果你拿两个 Member
s,这个 Comparator
按照你想要的方式订购它们?这是一个很容易编写的测试,不会陷入 Comparator
.
的细节之中
List<Member> members = List.of(m1, m2);
assertEquals(m1, Collections.min(members, comparator)); // For example.
assertEquals(m2, Collections.max(members, comparator)); // For example.
一些断言可能如下所示:
assertTrue(comparator.compare(m1, m1) == 0);
assertTrue(comparator.compare(m1, m2) > 0);
assertTrue(comparator.compare(m2, m1) < 0);
我需要测试 compare() 方法,但我对如何测试感到困惑。我能看看怎么做吗?
public class MemberComparator implements Comparator<Member> {
private final String clientId;
public MemberComparator(String clientId) {
this.clientId = clientId;
}
@Override
public int compare(Member m1, Member m2) {
if (m1.getClientId().startsWith(clientId)) {
return m2.getClientId().startsWith(clientId) ? m1.getClientId().compareTo(m2.getClientId())
: -1;
} else {
return m2.getClientId().startsWith(clientId) ? 1
: m1.getClientId().compareTo(m2.getClientId());
}
}
}
到目前为止,这是我在测试中创建的。我怎样才能让它工作?假设我不更改 MemberComparator class.
的当前方法,我应该怎么做,因为这种方式不起作用class MemberComparatorTest {
//private MemberComparator caseID_test;
//private final MemberComparator memberComparator = new MemberComparator("jake");
@Test
void testEqual() {
Member m1 = new Member();
Member m2 = new Member();
int result = memberComparator.compare(m1,m2);
//assertTrue("expected to be equal", result == 0);
}
}
写 Comparator
时需要回答两个问题:
- 是否满足
Comparator
接口的要求? - 它能满足您的需求吗?
第一个相当难以编写测试;我认为最好使用“已知良好”模式编写一些东西,以帮助您从代码中推断出它的正确性。
在 Comparator
的情况下,“已知良好”模式是您从链接方法中看到的:
// This boolean comparison may be the wrong way round, I never remember which way is which. If so, reverse it.
Comparator.comparing(m -> m.getClientId().startsWith(clientId))
.thenComparing(Member::getClientId)
你比较第一件事,return如果它们不同;你比较第二件事,return 如果它们不同,等等
如果您使用的是 Java 8+,则可以使用上面的代码:这完全可以 Comparator
。如果您不能使用它(无论出于何种原因),您的 compare
方法可以重写为:
int compareSw = Boolean.compare(m1.getClientId().startsWith(clientId), m2.getClientId().startsWith(clientId));
if (compareSw != 0) {
return compareSw;
}
return m1.getClientId().compareTo(m2.getClientId());
因为这遵循“已知良好”模式,所以通过检查可以看出满足Comparator
接口的要求。
(当然,你必须小心思考“对我来说看起来不错!”,因为你可能会错过一些东西,例如使用 m1.getClientId()
两次而不是 m1.getClientId()
和 m2.getClientId()
。但是,通过对以下内容进行充分测试,可以发现这种缺陷。
那么这只是一个测试问题,以确保它你想要什么:也就是说,如果你拿两个 Member
s,这个 Comparator
按照你想要的方式订购它们?这是一个很容易编写的测试,不会陷入 Comparator
.
List<Member> members = List.of(m1, m2);
assertEquals(m1, Collections.min(members, comparator)); // For example.
assertEquals(m2, Collections.max(members, comparator)); // For example.
一些断言可能如下所示:
assertTrue(comparator.compare(m1, m1) == 0);
assertTrue(comparator.compare(m1, m2) > 0);
assertTrue(comparator.compare(m2, m1) < 0);