Assert regex matches in JUnit

2019-01-21 16:06发布

问题:

Ruby's Test::Unit has a nice assert_matches method that can be used in unit tests to assert that a regex matches a string.

Is there anything like this in JUnit? Currently, I do this:

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

回答1:

If you use assertThat() with a Hamcrest matcher that tests for regex matches, then if the assertion fails you'll get a nice message that indicates expected pattern and actual text. The assertion will read more fluently also, e.g.

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


回答2:

No other choice that I know. Just checked the assert javadoc to be sure. Just a tiny little change, though:

assertTrue(actual.matches(expectedRegex));

EDIT: I have been using the Hamcrest matchers since pholser's answer, check that out too!



回答3:

You can use Hamcrest, but you have to write your own matcher:

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);
    }
}

usage

import org.junit.Assert;


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


回答4:

You can use Hamcrest and jcabi-matchers:

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

More details here: Regular Expression Hamcrest Matchers.

You will need these two dependencies in 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>


回答5:

Because I was also looking for this functionality, I have started a project on GitHub called regex-tester. It's a library that helps ease testing regular expressions in Java (only works with JUnit currently).

The library is very limited right now, but it does have a Hamcrest matcher that works like this

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

More about how to use regex-tester is here.



回答6:

A matcher similar to Ralph's implementation has been added to the official Java Hamcrest matchers library. Unfortunately, it's not yet available in a release package. The class is on GitHub though if you want a look.



回答7:


it's not JUnit but here is another way with fest-assert :

assertThat(myTestedValue).as("your value is so so bad").matches(expectedRegex);


回答8:

another alternative using assertj. this approach is nice as it allows you to pass the pattern object directly.

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


回答9:

There is corresponding matcher in Hamcrest: org.hamcrest.Matchers.matchesPattern(String regex).

As development of Hamcrest stalled you can't use latest available v1.3:

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

Instead you need to use new dev series (but still dated by Jan 2015):

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

or even better:

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")
}

In test:

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


标签: java regex junit