jUnit中的AssertContains对字符串进行断言

251

有没有更好的方法来编写jUnit测试用例?

String x = "foo bar";
Assert.assertTrue(x.contains("foo"));

11
我认为这已经很不错了,建议的选项可读性较差。 - The Godfather
10
@TheGodfather,虽然不太易读,但会产生更有意义的断言错误(例如,接受的响应将显示字符串的差异,而OP的解决方案在失败时只会显示“False when expected True”)。 - Mike
1
一个断言之所以“更好”,是因为它在失败时提供了更好的错误信息。它在代码中的可读性次于此,因为你只有在它失败时才需要查看代码,而失败消息是你首先看到的东西。 - rjmunro
问题本身应该是被接受的答案:D - d1Master
@rjmunro 你可以将自己的信息作为 assertTrue 的参数 传递,例如 Assert.assertTrue("应该包含子字符串 'foo'", x.contains("foo")); - rook218
12个回答

376

如果你加入Hamcrest和JUnit4,你可以这样做:

String x = "foo bar";
Assert.assertThat(x, CoreMatchers.containsString("foo"));

通过使用一些静态导入,它看起来更好:

assertThat(x, containsString("foo"));
需要的静态导入如下:
import static org.hamcrest.MatcherAssert.assertThat;
import static org.hamcrest.CoreMatchers.containsString;

8
请确保使用的是 org.junit.Assert 而不是 junit.framework.Assert,因为后者没有 Hamcrest Matcher 的 assertThat() 方法。 - Visionary Software Solutions
16
在运行JUnit 4.10时,我认为要使用的类是org.junit.matchers.JUnitMatchers,例如:assertThat("something", JUnitMatchers.containsString("some")); - Ewen Cartwright
2
一个失败的 assertThat 的失败信息比一个 assertTrue 更有帮助。 - Mike Rylander
3
需要的静态导入是 import static org.junit.Assert.assertThat; import static org.hamcrest.CoreMatchers.containsString; - 只是为了避免给某人带来麻烦。 - eis
5
在最新的API中,hamcrest-library依赖项中包含org.hamcrest.Matchers.containsString; - eis
显示剩余4条评论

22

尽可能使用 fest assert 2.0,编辑: assertj 可能有更多的断言(一个分支)

assertThat(x).contains("foo");

我在AssertJ.assertThat中没有找到contains方法。相反,我找到了这个 - org.assertj.core.api.Assertions.assertThat(conversionException).hasMessageContaining("some substring"); - Raj
抱歉,我认为我上面的评论不适用于这个答案的情境。我当时在处理一个不同的用例,需要检查异常消息中是否包含子字符串。 - Raj

11

使用 Hamcrest Matcher 的 containsString() 方法

// Hamcrest assertion
assertThat(person.getName(), containsString("myName"));

// Error Message
java.lang.AssertionError:
Expected: a string containing "myName"
     got: "some other name"

您可以选择添加更详细的错误信息。

// Hamcrest assertion with custom error message
assertThat("my error message", person.getName(), containsString("myName"));

// Error Message
java.lang.AssertionError: my error message
Expected: a string containing "myName"
     got: "some other name"

我已将我的答案发布在一个重复的问题这里


9

你可以使用 assertj 来进行流畅的断言。它有很多能力,可以以更加易读的方式编写断言,让用户更容易理解。

在你的情况下,可以这样做:

 String x = "foo bar";
 assertThat(x).contains("foo");

它不仅适用于字符串,还可以以更友好的方式断言列表、集合等等。


7

示例 (junit版本- 4.13)

import static org.assertj.core.api.Assertions.assertThat;
import org.junit.Test;

public class TestStr {

@Test
public void testThatStringIsContained(){
    String testStr = "hi,i am a test string";
    assertThat(testStr).contains("test");
 }

}

这应该是被接受的答案。最简单且有效。 - ajpieri
感谢@ajpieri。 - Muriithi Derrick

5

使用新的assertThat语法和Hamcrest一起使用。

这个功能从JUnit 4.4开始可用。


5

虽然有点晚了,但是为了更新一下,我使用以下语法完成了它。

import org.hamcrest.core.StringContains;
import org.junit.Assert;

Assert.assertThat("this contains test", StringContains.containsString("test"));

2
另一种变体是:
Assert.assertThat(actual, new Matches(expectedRegex));

此外,在org.mockito.internal.matchers中还有一些其他有趣的匹配器,例如StartWithContains等。

2
断言库变体。
import org.assertj.core.api.Assertions;
Assertions.assertThat(actualStr).contains(subStr);

1

我写了这个实用方法


public static void assertContains(String string, String subString) {
    Assertions.assertTrue(string.contains(subString));
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接