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

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.


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!


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

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>

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 .


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.


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]+$"));

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

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);
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.