在JUnit中声明正则表达式匹配


81

RubyTest::Unit有一个很好的assert_matches方法,可以在单元测试中使用它来断言正则表达式与字符串匹配。

JUnit中是否有类似的东西?目前,我这样做:

assertEquals(true, actual.matches(expectedRegex));

Answers:


97

如果assertThat()与用于测试正则表达式匹配项的Hamcrest匹配器一起使用,则如果断言失败,您将收到一条漂亮的消息,指出预期的模式和实际文本。该断言也将更加流利,例如

assertThat("FooBarBaz", matchesPattern("^Foo"));

51
需要明确的matchesPattern是,hamcrest AFAICT中实际上不存在这样的匹配器方法,您必须编写自己的匹配器。
pimlottc 2014年

7
matchesPatternjcabi-
matchers中

20
Hamcrest 2.0有Matchers.matchesPattern(String)现内置:github.com/hamcrest/JavaHamcrest/blob/master/hamcrest-library/...
hinneLinks

4
@hinneLinks指的是永久链接:github.com/hamcrest/JavaHamcrest/blob/…–
pioto

54

我没有其他选择。只需检查断言javadoc即可确定。不过,这只是一个小小的变化:

assertTrue(actual.matches(expectedRegex));

编辑:自从pholser回答以来,我一直在使用Hamcrest匹配器,也请检查一下!


1
是的,assertTrue()绝对更好。我怪我不知道Eclipse的自动完成功能。;)
Josh Glover

4
assertTrue无法为您提供尽可能多的详细信息assertEqualsassertThat测试失败的时间
Mike Valenty 2012年

1
@Michael当然可以。assertTrue("Expected string matching '" +expectedRegex+ "'. Got: "+actual, actual.matches(expectedRegex));。虽然不如Hamcrest好。
MikeFHay 2013年

@MikeValenty如果您只是将值与进行比较is(true),那么assertThat您所获得的详细信息将比其多assertTrue。为了获得正确的错误消息,您需要一个不同的匹配器(或者按照@MikeFHay的建议手动构造该消息)。
ThrawnCA

20

您可以使用Hamcrest,但必须编写自己的匹配器:

public class RegexMatcher extends TypeSafeMatcher<String> {

    private final String regex;

    public RegexMatcher(final String regex) {
        this.regex = regex;
    }

    @Override
    public void describeTo(final Description description) {
        description.appendText("matches regex=`" + regex + "`");
    }

    @Override
    public boolean matchesSafely(final String string) {
        return string.matches(regex);
    }


    public static RegexMatcher matchesRegex(final String regex) {
        return new RegexMatcher(regex);
    }
}

用法

import org.junit.Assert;


Assert.assertThat("test", RegexMatcher.matchesRegex(".*est");

18

您可以使用Hamcrest和jcabi-matchers

import static com.jcabi.matchers.RegexMatchers.matchesPattern;
import static org.junit.Assert.assertThat;
assertThat("test", matchesPattern("[a-z]+"));

此处有更多详细信息:正则表达式Hamcrest Matchers

您将在classpath中需要以下两个依赖项:

<dependency>
  <groupId>org.hamcrest</groupId>
  <artifactId>hamcrest-core</artifactId>
  <version>1.3</version>
  <scope>test</scope>
</dependency>
<dependency>
  <groupId>com.jcabi</groupId>
  <artifactId>jcabi-matchers</artifactId>
  <version>1.3</version>
  <scope>test</scope>
</dependency>

我发现不需要hamcrest-core依赖
JohnP2

4

因为我也在寻找此功能,所以我在GitHub上启动了一个名为regex-tester的项目。这是一个有助于简化Java正则表达式测试的库(当前仅适用于JUnit)。

该库目前非常有限,但确实有一个像这样的Hamcrest匹配器

assertThat("test", doesMatchRegex("tes.+"));
assertThat("test", doesNotMatchRegex("tex.+"));

有关如何使用regex-tester的更多信息,请点击此处


4

与Ralph的实现类似的匹配器已添加到官方Java Hamcrest匹配器库。不幸的是,它尚未在发行包中提供。该类在GitHub上,但是如果您想看的话。


3

Hamcrest中有相应的匹配器:org.hamcrest.Matchers.matchesPattern(String regex)

随着Hamcrest开发的停滞,您无法使用最新的v1.3:

testCompile("org.hamcrest:hamcrest-library:1.3")

相反,您需要使用新的开发人员系列(但日期仍为2015年1月):

testCompile("org.hamcrest:java-hamcrest:2.0.0.0")

甚至更好:

configurations {
    testCompile.exclude group: "org.hamcrest", module: "hamcrest-core"
    testCompile.exclude group: "org.hamcrest", module: "hamcrest-library"
}
dependencies {
    testCompile("org.hamcrest:hamcrest-junit:2.0.0.0")
}

在测试中:

Assert.assertThat("123456", Matchers.matchesPattern("^[0-9]+$"));

我收到错误消息:在模块jetified-hamcrest-core-1.3.jar(org.hamcrest:hamcrest-core:1.3)和jetified-java-hamcrest-2.0.0.0.jar(org.hamcrest)模块中找到重复的类org.hamcrest.BaseDescription :java-hamcrest:2.0.0.0)
a_subscriber

2

使用assertj的另一种选择。这种方法很好,因为它允许您直接传递模式对象。

import static org.assertj.core.api.Assertions.assertThat;
assertThat("my\nmultiline\nstring").matches(Pattern.compile("(?s)my.*string", Pattern.MULTILINE));

1


它不是JUnit,但是这是fest-assert的另一种方式:

assertThat(myTestedValue).as("your value is so so bad").matches(expectedRegex);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.