Assertj是一个流行的Java断言库,它提供了丰富的断言方法,可以帮助开发人员编写更加清晰和可读性强的测试代码。在Assertj中,可以使用自定义断言来扩展其功能,以便更好地满足特定的测试需求。
对于可迭代对象,可以通过实现org.assertj.core.api.iterable.ThrowingExtractor
接口来创建自定义断言。该接口定义了一个extractThrows
方法,用于从可迭代对象中提取需要断言的值。下面是一个示例:
import org.assertj.core.api.AbstractIterableAssert;
import org.assertj.core.api.Assertions;
import org.assertj.core.api.ThrowableAssert;
import java.util.function.Consumer;
public class CustomIterableAssert<T> extends AbstractIterableAssert<CustomIterableAssert<T>, Iterable<? extends T>, T> {
protected CustomIterableAssert(Iterable<? extends T> actual) {
super(actual, CustomIterableAssert.class);
}
public static <T> CustomIterableAssert<T> assertThat(Iterable<? extends T> actual) {
return new CustomIterableAssert<>(actual);
}
public CustomIterableAssert<T> containsCustom(T expected) {
isNotNull();
for (T element : actual) {
if (element.equals(expected)) {
return myself;
}
}
throwAssertionError("Expecting <%s> to contain <%s>", actual, expected);
return myself;
}
public CustomIterableAssert<T> containsCustom(T... expected) {
isNotNull();
for (T element : expected) {
containsCustom(element);
}
return myself;
}
public CustomIterableAssert<T> containsCustomExactly(T... expected) {
isNotNull();
hasSameSizeAs(expected);
containsCustom(expected);
return myself;
}
public CustomIterableAssert<T> containsCustomExactlyInAnyOrder(T... expected) {
isNotNull();
hasSameSizeAs(expected);
containsCustomInAnyOrder(expected);
return myself;
}
public CustomIterableAssert<T> containsCustomInAnyOrder(T... expected) {
isNotNull();
for (T element : expected) {
containsCustom(element);
}
return myself;
}
public CustomIterableAssert<T> containsCustomOnly(T... expected) {
isNotNull();
containsCustomExactly(expected);
return myself;
}
public CustomIterableAssert<T> containsCustomOnlyOnce(T expected) {
isNotNull();
containsCustom(expected);
containsCustomExactly(expected);
return myself;
}
public CustomIterableAssert<T> doesNotContainCustom(T unexpected) {
isNotNull();
for (T element : actual) {
if (element.equals(unexpected)) {
throwAssertionError("Expecting <%s> not to contain <%s>", actual, unexpected);
}
}
return myself;
}
public CustomIterableAssert<T> doesNotContainCustom(T... unexpected) {
isNotNull();
for (T element : unexpected) {
doesNotContainCustom(element);
}
return myself;
}
public CustomIterableAssert<T> doesNotContainNull() {
isNotNull();
for (T element : actual) {
if (element == null) {
throwAssertionError("Expecting <%s> not to contain null elements", actual);
}
}
return myself;
}
public CustomIterableAssert<T> doesNotHaveDuplicates() {
isNotNull();
for (T element : actual) {
int count = 0;
for (T other : actual) {
if (element.equals(other)) {
count++;
}
}
if (count > 1) {
throwAssertionError("Expecting <%s> not to have duplicates", actual);
}
}
return myself;
}
public CustomIterableAssert<T> hasSize(int expectedSize) {
isNotNull();
int actualSize = 0;
for (T element : actual) {
actualSize++;
}
if (actualSize != expectedSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, expectedSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSizeGreaterThan(int expectedSize) {
isNotNull();
int actualSize = 0;
for (T element : actual) {
actualSize++;
}
if (actualSize <= expectedSize) {
throwAssertionError("Expecting size of <%s> to be greater than <%s> but was <%s>", actual, expectedSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSizeLessThan(int expectedSize) {
isNotNull();
int actualSize = 0;
for (T element : actual) {
actualSize++;
}
if (actualSize >= expectedSize) {
throwAssertionError("Expecting size of <%s> to be less than <%s> but was <%s>", actual, expectedSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSizeBetween(int lowerBound, int upperBound) {
isNotNull();
int actualSize = 0;
for (T element : actual) {
actualSize++;
}
if (actualSize < lowerBound || actualSize > upperBound) {
throwAssertionError("Expecting size of <%s> to be between <%s> and <%s> but was <%s>", actual, lowerBound, upperBound, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(Iterable<?> other) {
isNotNull();
int actualSize = 0;
int otherSize = 0;
for (T element : actual) {
actualSize++;
}
for (Object element : other) {
otherSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(Object[] other) {
isNotNull();
int actualSize = 0;
int otherSize = other.length;
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(int[] other) {
isNotNull();
int actualSize = 0;
int otherSize = other.length;
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(long[] other) {
isNotNull();
int actualSize = 0;
int otherSize = other.length;
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(float[] other) {
isNotNull();
int actualSize = 0;
int otherSize = other.length;
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(double[] other) {
isNotNull();
int actualSize = 0;
int otherSize = other.length;
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(short[] other) {
isNotNull();
int actualSize = 0;
int otherSize = other.length;
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(byte[] other) {
isNotNull();
int actualSize = 0;
int otherSize = other.length;
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(char[] other) {
isNotNull();
int actualSize = 0;
int otherSize = other.length;
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(String other) {
isNotNull();
int actualSize = 0;
int otherSize = other.length();
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(CharSequence other) {
isNotNull();
int actualSize = 0;
int otherSize = other.length();
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(byte[] other, Charset charset) {
isNotNull();
int actualSize = 0;
int otherSize = new String(other, charset).length();
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(InputStream other) throws IOException {
isNotNull();
int actualSize = 0;
int otherSize = IOUtils.toByteArray(other).length;
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(Reader other) throws IOException {
isNotNull();
int actualSize = 0;
int otherSize = IOUtils.toCharArray(other).length;
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(File other) throws IOException {
isNotNull();
int actualSize = 0;
int otherSize = FileUtils.sizeOf(other);
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(Path other) throws IOException {
isNotNull();
int actualSize = 0;
int otherSize = (int) Files.size(other);
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public CustomIterableAssert<T> hasSameSizeAs(URL other) throws IOException {
isNotNull();
int actualSize = 0;
int otherSize = IOUtils.toByteArray(other).length;
for (T element : actual) {
actualSize++;
}
if (actualSize != otherSize) {
throwAssertionError("Expecting size of <%s> to be <%s> but was <%s>", actual, otherSize, actualSize);
}
return myself;
}
public ThrowableAssert.ThrowingCallable extractThrows(Consumer<T> consumer) {
return () -> {
for (T element : actual) {
consumer.accept(element);
}
};
}
}
在上面的示例中,我们创建了一个名为CustomIterableAssert
的自定义断言类,继承自AbstractIterableAssert
。该类提供了一系列用于断言可迭代对象的方法,例如containsCustom
、doesNotContainCustom
、hasSize
等。这些方法可以根据具体的测试需求进行扩展和定制。
使用自定义断言时,可以通过静态方法assertThat
创建一个CustomIterableAssert
对象,并使用断言方法进行断言。例如:
List<String> list = Arrays.asList("apple", "banana", "orange");
CustomIterableAssert.assertThat(list).containsCustom("apple").hasSize(3);
在上面的示例中,我们使用自定义断言containsCustom
断言列表中包含"apple",并使用hasSize
断言列表的大小为3。
关于Assertj和自定义断言的更多信息,可以参考腾讯云的相关文档和示例代码:
希望以上信息能够帮助你理解Assertj如何为可迭代对象创建自定义断言。如果还有其他问题,请随时提问。