首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Assertj+如何为可迭代对象创建自定义断言

Assertj是一个流行的Java断言库,它提供了丰富的断言方法,可以帮助开发人员编写更加清晰和可读性强的测试代码。在Assertj中,可以使用自定义断言来扩展其功能,以便更好地满足特定的测试需求。

对于可迭代对象,可以通过实现org.assertj.core.api.iterable.ThrowingExtractor接口来创建自定义断言。该接口定义了一个extractThrows方法,用于从可迭代对象中提取需要断言的值。下面是一个示例:

代码语言:txt
复制
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。该类提供了一系列用于断言可迭代对象的方法,例如containsCustomdoesNotContainCustomhasSize等。这些方法可以根据具体的测试需求进行扩展和定制。

使用自定义断言时,可以通过静态方法assertThat创建一个CustomIterableAssert对象,并使用断言方法进行断言。例如:

代码语言:txt
复制
List<String> list = Arrays.asList("apple", "banana", "orange");
CustomIterableAssert.assertThat(list).containsCustom("apple").hasSize(3);

在上面的示例中,我们使用自定义断言containsCustom断言列表中包含"apple",并使用hasSize断言列表的大小为3。

关于Assertj和自定义断言的更多信息,可以参考腾讯云的相关文档和示例代码:

希望以上信息能够帮助你理解Assertj如何为可迭代对象创建自定义断言。如果还有其他问题,请随时提问。

页面内容是否对你有帮助?
有帮助
没帮助

相关·内容

学了C++不会STL,简直少了左膀右臂

容器(Container): 是一种数据结构,如list,vector,和deques ,以模板类的方法提供。为了访问容器中的数据,可以使用由容器类输出的迭代器; 迭代器(Iterator): 提供了访问容器中对象的方法。例如,可以使用一对迭代器指定list或vector中的一定范围的对象。迭代器就如同一个指针。事实上,C++的指针也是一种迭代器。但是,迭代器也可以是那些定了operator*()以及其他类似于指针的操作符地方法的类对象; 算法(Algorithm): 是用来操作容器中的数据的模板函数。例如,STL用sort()来对一个vector中的数据进行排序,用find()来搜索一个list中的对象,函数本身与他们操作的数据的结构和类型无关,因此他们可以在从简单数组到高度复杂容器的任何数据结构上使用; 仿函数(Functor) 适配器(Adaptor) 分配器(allocator) 仿函数、适配器、与分配器用的比较少,甚至没用过!在这里不做说明,有兴趣可以自己学习一下,那个东西C++软件工程可能用的比较多。

02
领券