Comparator Verifier #
Comparison method violates its general contract! #
Ако сте написали компаратор, който не спазва договора, описан в Javadoc, ето как обикновено разбирате за това:
java.lang.IllegalArgumentException: Comparison method violates its general contract!
at java.util.ComparableTimSort.mergeHi(ComparableTimSort.java:835)
at java.util.ComparableTimSort.mergeAt(ComparableTimSort.java:453)
at java.util.ComparableTimSort.mergeForceCollapse(ComparableTimSort.java:392)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:191)
at java.util.ComparableTimSort.sort(ComparableTimSort.java:146)
at java.util.Arrays.sort(Arrays.java:472)
at java.util.Collections.sort(Collections.java:155)
...
Нека го оправим.
Първи стъпки #
Comparator Verifier е интуитивно API за тестване дали дадена имплементация на Comparator
спазва изисквания договор, чрез написване на обикновен юнит тест.
Добавяне на Зависимост #
Добавете comparatorverifier
към вашия файл pom.xml
.
<dependency>
<groupId>io.github.tomregan</groupId>
<artifactId>comparatorverifier</artifactId>
<version>1.0.0</version>
<scope>test</scope>
</dependency>
Добавете comparatorverifier
към вашия файл build.gradle
.
dependencies {
testImplementation 'io.github.tomregan:comparatorverifier:1.0.0'
}
Добавете comparatorverifier
към вашия файл build.gradle.kts
.
dependencies {
testImplementation("io.github.tomregan:comparatorverifier:1.0.0")
}
Напишете Тест #
Напишете юнит тест за вашия компаратор.
@Test
void comparatorContract() {
ComparatorVerifier.forComparator(FooComparator.class).verify();
}
Допълнително използване #
Примерно използване с JUnit #
Comparator Verifier позволява конфигурируема верификация, включваща както строги, така и по-свободни проверки.
По-долу са показани примерни JUnit тестове с различни конфигурации на Comparator Verifier.
По-свободна верификация (Permissive) #
import co.mp.ComparatorVerifier;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.Test;
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
final class FooComparatorTest {
@Test
void comparator_contract_is_met() {
ComparatorVerifier.forComparator(FooComparator.class)
.permissive()
.withExamples(new Foo("x"), new Foo("y"))
.verify();
}
}
Строга верификация (Strict) #
import co.mp.ComparatorVerifier;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.Test;
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
final class FooComparatorTest {
@Test
void comparator_can_be_serialized_in_a_tree_set() {
ComparatorVerifier.forComparator(FooComparator.class)
.strict()
.withExamples(new Foo("a"), new Foo("b"))
.verify();
}
}
Верификация с потиснати предупреждения #
Компаратор, който не отговаря на договора за Comparator, не е безопасен за използване с Java колекции.Обмислете използване на
permissive()
илиstrict()
за промяна на поведението на верификацията.
import co.mp.ComparatorVerifier;
import co.mp.Warning;
import org.junit.jupiter.api.DisplayNameGeneration;
import org.junit.jupiter.api.DisplayNameGenerator;
import org.junit.jupiter.api.Test;
@DisplayNameGeneration(DisplayNameGenerator.ReplaceUnderscores.class)
final class FooComparatorTest {
@Test
void comparator_contract_is_met() {
ComparatorVerifier.forComparator(FooComparator.class)
.withExamples(new Foo("1"), new Foo("2"), new Foo("3"))
.suppress(Warning.TRANSITIVITY)
.verify();
}
}