gpt4 book ai didi

java - 我如何断言一个List恰好包含一个特定类的一个实例?

转载 作者:行者123 更新时间:2023-12-03 21:48:03 26 4
gpt4 key购买 nike

我想测试一个列表包含一个对象的实例。

例如,对于一个实例:

assertThat(mylist).containsExactly(Matchers.any(ExpectedType.class));


从测试的 obj返回的数组确实包含实例 ExpectedType的一个对象。
但是我的测试失败了:


java.lang.AssertionError:<[ExpectedType @ 7c781c42]>完全包含<[ExpectedType的实例]>是不正确的。它缺少<[ExpectedType的实例]>,并且具有意外的项目<[ExpectedType @ 7c781c42]>


如何编写此测试?

最佳答案

您正在尝试编写一个测试,以使用Hamcrest和Truth查看List是否恰好包含特定类的一个实例。相反,您应该使用Hamcrest或Truth编写此测试。 Hamcrest和Truth都是用于使测试更具表现力的库,每个库都有自己的特定用法,样式和语法。如果愿意,您可以在测试中将它们并排使用,但是在执行过程中将它们的方法链接在一起是行不通的。 (也许您会感到困惑,因为这两个库都可以具有以assertThat开头的断言?)因此对于此特定测试,您需要选择其中一个并继续使用它。

但是,这两个库都缺少检查List是否具有一个且只有一个满足条件的项的内置功能。因此,对于这两个库,您都有两个选择:要么可以对列表进行一些预处理,以便可以使用内置的断言,要么可以扩展库的语言以提供此功能。

下面是一个示例类,演示了两个库的两个选项:

import com.google.common.collect.FluentIterable;
import com.google.common.truth.*;
import org.hamcrest.*;
import org.junit.Test;

import java.util.*;

import static com.google.common.truth.Truth.assertAbout;
import static com.google.common.truth.Truth.assert_;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.Matchers.*;

public class ExactlyOneInstanceTest {
List<Object> myList = Arrays.asList("", 3, 'A', new Object());

@Test
public void hamcrestBuiltInTestExactlyOneInstance() {
long theNumberOfStringsInMyList = myList.stream().filter(o -> o instanceof String).count();
assertThat(theNumberOfStringsInMyList, equalTo(1L));
}

@Test
public void hamcrestExtendedTestExactlyOneInstance() {
assertThat(myList, HasExactlyOne.itemThat(is(instanceOf(String.class))));
}

@Test
public void truthBuiltInTestExactlyOneInstance() {
long theNumberOfStringsInMyList = myList.stream().filter(o -> o instanceof String).count();
// can't static import Truth.assertThat because of name clash,
// but we can use this alternative form
assert_().that(theNumberOfStringsInMyList).isEqualTo(1);
}

@Test
public void truthExtendedTestExactlyOneInstance() {
assertAbout(iterable()).that(myList).containsExactlyOneInstanceOf(String.class);
}


// Hamcrest custom matcher
static class HasExactlyOne<T> extends TypeSafeDiagnosingMatcher<Iterable<? super T>> {
Matcher<? super T> elementMatcher;

HasExactlyOne(Matcher<? super T> elementMatcher) {
this.elementMatcher = elementMatcher;
}

@Factory
public static <T> Matcher<Iterable<? super T>> itemThat(Matcher<? super T> itemMatcher) {
return new HasExactlyOne<>(itemMatcher);
}

@Override
public void describeTo(Description description) {
description
.appendText("a collection containing exactly one item that ")
.appendDescriptionOf(elementMatcher);
}

@Override
protected boolean matchesSafely(Iterable<? super T> item, Description mismatchDescription) {
return FluentIterable.from(item).filter(o -> elementMatcher.matches(o)).size() == 1;
}
}

// Truth custom extension
static <T> SubjectFactory<ExtendedIterableSubject<T>, Iterable<T>> iterable() {
return new SubjectFactory<ExtendedIterableSubject<T>, Iterable<T>>() {
@Override
public ExtendedIterableSubject<T> getSubject(FailureStrategy fs, Iterable<T> target) {
return new ExtendedIterableSubject<>(fs, target);
}
};
}

static class ExtendedIterableSubject<T> extends IterableSubject<ExtendedIterableSubject<T>, T, Iterable<T>> {
ExtendedIterableSubject(FailureStrategy failureStrategy, Iterable<T> list) {
super(failureStrategy, list);
}

void containsExactlyOneInstanceOf(Class<?> clazz) {
if (FluentIterable.from(getSubject()).filter(clazz).size() != 1) {
fail("contains exactly one instance of", clazz.getName());
}
}
}
}


尝试运行并查看该类,并使用最适合您的方式。在编写将来的测试时,只需尝试使用可用的内置断言,并尝试使 @Test方法及其断言的意图立即可读。如果看到您多次编写相同的代码,或者测试方法不是那么容易阅读,则可以重构和/或扩展所用库的语言。重复进行,直到所有内容都经过测试并且所有测试都易于理解为止。请享用!

关于java - 我如何断言一个List恰好包含一个特定类的一个实例?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34528085/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com