如何为 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 时需要回答两个问题:

  1. 是否满足Comparator接口的要求?
  2. 它能满足您的需求吗?

第一个相当难以编写测试;我认为最好使用“已知良好”模式编写一些东西,以帮助您从代码中推断出它的正确性。

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()。但是,通过对以下内容进行充分测试,可以发现这种缺陷。

那么这只是一个测试问题,以确保它你想要什么:也就是说,如果你拿两个 Members,这个 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);