Potwierdź dopasowania wyrażeń regularnych w JUnit

84

Ruby Test::Unitma fajną assert_matchesmetodę, której można użyć w testach jednostkowych, aby potwierdzić, że wyrażenie regularne pasuje do łańcucha.

Czy jest coś takiego w JUnit? Obecnie robię to:

assertEquals(true, actual.matches(expectedRegex));
Josh Glover
źródło

Odpowiedzi:

99

Jeśli używasz assertThat()z dopasowaniem Hamcrest, który testuje dopasowania wyrażeń regularnych, to jeśli asercja się nie powiedzie, otrzymasz ładny komunikat, który wskazuje oczekiwany wzorzec i rzeczywisty tekst. Asercja będzie czytać również płynniej, np

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

z Hamcrest 2 możesz znaleźć matchesPatternmetodę na MatchesPattern.matchesPattern.

pholser
źródło
21
Hamcrest 2.0 ma Matchers.matchesPattern(String)teraz wbudowany: github.com/hamcrest/JavaHamcrest/blob/master/hamcrest-library/ ...
hinneLinks
5
Permalink do tego, do czego odnosi się @hinneLinks
pioto
54

Nie ma innego wyboru, który znam. Po prostu sprawdziłem asercję javadoc, aby się upewnić. Tylko niewielka zmiana:

assertTrue(actual.matches(expectedRegex));

EDYCJA: Używam dopasowań Hamcrest od czasu odpowiedzi pholera, sprawdź też!

Miquel
źródło
1
Ach tak, assertTrue()jest zdecydowanie ładniejszy. Winię autouzupełnianie Eclipse za to, że o tym nie wiem. ;)
Josh Glover
4
assertTruenie mogę podać tak wielu szczegółów, jak assertEqualslub assertThatkiedy test się nie powiedzie
Mike Valenty
1
@Michael Pewnie, że tak. assertTrue("Expected string matching '" +expectedRegex+ "'. Got: "+actual, actual.matches(expectedRegex));. Jednak nie jest tak przyjemny jak Hamcrest.
MikeFHay
@MikeValenty Jeśli porównujesz tylko wartość is(true), to assertThatnie podaje więcej szczegółów niż assertTrueto. Aby otrzymać prawidłowe komunikaty o błędach, potrzebujesz innego dopasowania (lub możesz utworzyć wiadomość ręcznie, zgodnie z sugestią @MikeFHay).
ThrawnCA
20

Możesz użyć Hamcrest, ale musisz napisać własnego dopasowania:

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

stosowanie

import org.junit.Assert;


Assert.assertThat("test", RegexMatcher.matchesRegex(".*est");
Ralph
źródło
18

Możesz użyć Hamcrest i jcabi-matchers :

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

Więcej szczegółów tutaj: Regular Expression Hamcrest Matchers .

Będziesz potrzebować tych dwóch zależności w ścieżce klas:

<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
źródło
Odkryłem, że zależność od rdzenia hamcrestu nie jest potrzebna
JohnP2
4

Ponieważ szukałem również tej funkcjonalności, zacząłem projekt na GitHub o nazwie regex-tester . Jest to biblioteka ułatwiająca testowanie wyrażeń regularnych w Javie (obecnie działa tylko z JUnit).

Biblioteka jest teraz bardzo ograniczona, ale ma narzędzie do dopasowywania Hamcrest, które działa w ten sposób

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

Więcej o tym, jak używać testera wyrażeń regularnych, znajdziesz tutaj .

Nick A. Watts
źródło
4

Został dopasowany podobny do implementacji Ralpha dodane do oficjalnej biblioteki dopasowań Java Hamcrest. Niestety nie jest jeszcze dostępny w pakiecie wydania. Jeśli chcesz zobaczyć, klasa jest na GitHubie .

Nick A. Watts
źródło
3

W Hamcrest znajduje się odpowiedni element dopasowujący: org.hamcrest.Matchers.matchesPattern (wyrażenie regularne String) .

Ponieważ rozwój Hamcrest utknął w martwym punkcie , nie można używać najnowszej dostępnej wersji 1.3:

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

Zamiast tego musisz użyć nowej serii deweloperów (ale nadal datowanej na styczeń 2015 ):

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

lub nawet lepiej:

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

W teście:

Assert.assertThat("123456", Matchers.matchesPattern("^[0-9]+$"));
gavenkoa
źródło
Pojawia się błąd: zduplikowana klasa org.hamcrest.BaseDescription znaleziona w modułach jetified-hamcrest-core-1.3.jar (org.hamcrest: hamcrest-core: 1.3) i jetified-java-hamcrest-2.0.0.0.jar (org.hamcrest : java-hamcrest: 2.0.0.0)
a_subscriber
2

inna alternatywa przy użyciu assertj. to podejście jest przyjemne, ponieważ umożliwia bezpośrednie przekazanie obiektu wzorca.

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


to nie jest JUnit, ale oto inny sposób z fest-assert:

assertThat(myTestedValue).as("your value is so so bad").matches(expectedRegex);
boly38
źródło