Aktivieren Sie Regex-Übereinstimmungen in JUnit

82

Ruby's Test::Unithat eine nette assert_matchesMethode, die in Unit-Tests verwendet werden kann, um zu behaupten, dass ein Regex mit einer Zeichenfolge übereinstimmt.

Gibt es so etwas in JUnit? Derzeit mache ich das:

assertEquals(true, actual.matches(expectedRegex));
Josh Glover
quelle

Antworten:

97

Wenn Sie assertThat()einen Hamcrest-Matcher verwenden , der auf Regex-Übereinstimmungen prüft, erhalten Sie eine fehlgeschlagene Meldung, die das erwartete Muster und den tatsächlichen Text angibt, wenn die Zusicherung fehlschlägt. Die Behauptung wird auch fließender gelesen, z

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

Mit Hamcrest 2 finden Sie eine matchesPatternMethode unter MatchesPattern.matchesPattern.

pholser
quelle
51
Um klar zu sein, matchesPatterngibt es in hamcrest AFAICT keine solche Matcher-Methode. Sie müssten Ihren eigenen Matcher schreiben.
Pimlottc
7
matchesPatternexistiert in jcabi-matchers
yegor256
21
Hamcrest 2.0 hat das Matchers.matchesPattern(String)jetzt eingebaute: github.com/hamcrest/JavaHamcrest/blob/master/hamcrest-library/…
hinneLinks
4
Permalink für das, worauf sich @hinneLinks bezieht: github.com/hamcrest/JavaHamcrest/blob/…
pioto
54

Keine andere Wahl, die ich kenne. Ich habe gerade den Assert Javadoc überprüft , um sicherzugehen. Nur eine kleine Änderung:

assertTrue(actual.matches(expectedRegex));

EDIT: Ich benutze die Hamcrest Matcher seit der Antwort von Pholser, schau dir das auch an!

Miquel
quelle
1
Ah ja, assertTrue()ist definitiv schöner. Ich beschuldige Eclipse's Auto-Complete, dass ich nichts davon weiß. ;)
Josh Glover
4
assertTrueassertEqualsassertThat
Ich
1
@ Michael Sicher kann es. assertTrue("Expected string matching '" +expectedRegex+ "'. Got: "+actual, actual.matches(expectedRegex));. Es ist allerdings nicht so schön wie Hamcrest.
MikeFHay
@MikeValenty Wenn Sie nur einen Wert mit vergleichen is(true), erhalten assertThatSie nicht mehr Details als assertTrue. Um die richtigen Fehlermeldungen zu erhalten, benötigen Sie einen anderen Matcher (oder Sie erstellen die Meldung manuell, wie von @MikeFHay vorgeschlagen).
ThrawnCA
20

Sie können Hamcrest verwenden, müssen jedoch Ihren eigenen Matcher schreiben:

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

Verwendung

import org.junit.Assert;


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

Sie können Hamcrest- und Jcabi-Matcher verwenden :

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

Weitere Details hier: Regular Expression Hamcrest Matchers .

Sie benötigen diese beiden Abhängigkeiten im Klassenpfad:

<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>
yegor256
quelle
Ich habe festgestellt, dass die Hamcrest-Core-Abhängigkeit nicht benötigt wird
JohnP2
4

Da ich auch nach dieser Funktionalität gesucht habe, habe ich auf GitHub ein Projekt namens Regex-Tester gestartet . Es ist eine Bibliothek, die das Testen regulärer Ausdrücke in Java erleichtert (funktioniert derzeit nur mit JUnit).

Die Bibliothek ist momentan sehr begrenzt, aber es gibt einen Hamcrest-Matcher, der so funktioniert

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

Weitere Informationen zur Verwendung des Regex-Testers finden Sie unter hier .

Nick A. Watts
quelle
4

Der offiziellen Java Hamcrest-Matcher-Bibliothek wurde ein Matcher hinzugefügt , der der Implementierung von Ralph ähnelt . Leider ist es noch nicht in einem Release-Paket verfügbar. Die Klasse ist jedoch auf GitHub, wenn Sie einen Blick darauf werfen möchten.

Nick A. Watts
quelle
3

In Hamcrest gibt es einen entsprechenden Matcher: org.hamcrest.Matchers.matchesPattern (String regex) .

Da die Entwicklung von Hamcrest ins Stocken geraten ist , können Sie die neueste verfügbare Version 1.3 nicht verwenden:

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

Stattdessen müssen Sie neue Entwicklungsserien verwenden (aber immer noch bis Januar 2015 datiert ):

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

oder noch besser:

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

Im Test:

Assert.assertThat("123456", Matchers.matchesPattern("^[0-9]+$"));
Gavenkoa
quelle
Ich erhalte die Fehlermeldung: Doppelte Klasse org.hamcrest.BaseDescription in den Modulen jetified-hamcrest-core-1.3.jar (org.hamcrest: hamcrest-core: 1.3) und jetified-java-hamcrest-2.0.0.0.jar (org.hamcrest) : Java-Hamcrest: 2.0.0.0)
a_subscriber
2

eine andere Alternative mit assertj. Dieser Ansatz ist hilfreich, da Sie das Musterobjekt direkt übergeben können.

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


es ist nicht JUnit, aber hier ist ein anderer Weg mit fest-assert:

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