How to test Comparator for JUnit test?

佐手、 提交于 2021-02-05 09:28:28

问题


I need to test the compare() method and i am confused on how. Can I see how to do this?

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());
        }
    }

}

So far, this is what i have created in my test. How can i get this to work? What should i do as this way isn't working, assuming i do not change the current approach to 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);

}

}


回答1:


Some assertions might look like:

assertTrue(comparator.compare(m1, m1) == 0);
assertTrue(comparator.compare(m1, m2) > 0);
assertTrue(comparator.compare(m2, m1) < 0);



回答2:


There are two questions you'd need to answer when writing a Comparator:

  1. Does it meet the requirements of the Comparator interface?
  2. Does it do what you need?

The first one is reasonably hard to write tests for; I'd argue it's better to write something using a "known good" pattern, in order to help you reason about its correctness from the code.

In the case of Comparator, the "known good" pattern is something that you see from the chaining methods:

// 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)

You compare the first thing, and return if they're different; you compare the second thing, and return if they're different, etc.

You could use the code above if you're using Java 8+: this gives a totally fine Comparator. If you can't use this (for whatever reason), your compare method could be rewritten as:

int compareSw = Boolean.compare(m1.getClientId().startsWith(clientId), m2.getClientId().startsWith(clientId));
if (compareSw != 0) {
  return compareSw;
}
return m1.getClientId().compareTo(m2.getClientId());

Because this follows the "known good" pattern, this can be seen to meet the requirements of the Comparator interface by inspection.

(Of course, you have to be careful about thinking "Looks Good To Me!", because you might miss something, e.g. using m1.getClientId() twice instead of both m1.getClientId() and m2.getClientId(). But that sort of defect would be caught by sufficient testing of the following).

Then it's just a matter of testing to make sure it does what you want: that is, if you take two Members, does this Comparator order them the way you want? That's an easy test to write, without getting bogged down in the details of the Comparator.

List<Member> members = List.of(m1, m2);
assertEquals(m1, Collections.min(members, comparator));  // For example.
assertEquals(m2, Collections.max(members, comparator));  // For example.


来源:https://stackoverflow.com/questions/65923065/how-to-test-comparator-for-junit-test

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!