Afirmar coincidencias de expresiones regulares en JUnit

81

Ruby's Test::Unittiene un buen assert_matchesmétodo que se puede usar en pruebas unitarias para afirmar que una expresión regular coincide con una cadena.

¿Hay algo parecido a esto en JUnit? Actualmente, hago esto:

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

Respuestas:

97

Si lo usa assertThat()con un comparador Hamcrest que prueba las coincidencias de expresiones regulares, entonces, si la afirmación falla, obtendrá un mensaje agradable que indica el patrón esperado y el texto real. La afirmación también se leerá con más fluidez, p. Ej.

assertThat("FooBarBaz", matchesPattern("^Foo"));
pholser
fuente
51
Para ser claros, no existe tal matchesPatternmétodo de emparejamiento en Hamcrest AFAICT, tendrías que escribir tu propio comparador.
pimlottc
7
matchesPatternexiste en jcabi-matchers
yegor256
20
Hamcrest 2.0 tiene Matchers.matchesPattern(String)ahora incorporado: github.com/hamcrest/JavaHamcrest/blob/master/hamcrest-library/…
hinneLinks
4
Enlace permanente para lo que @hinneLinks hace referencia: github.com/hamcrest/JavaHamcrest/blob/…
pioto
54

No hay otra opción que yo sepa. Simplemente verifique el javadoc de aserción para estar seguro. Sin embargo, solo un pequeño cambio:

assertTrue(actual.matches(expectedRegex));

EDITAR: He estado usando los comparadores de Hamcrest desde la respuesta de pholser, ¡compruébalo también!

Miquel
fuente
1
Ah, sí, assertTrue()definitivamente es mejor. Culpo al autocompletado de Eclipse por no saberlo. ;)
Josh Glover
4
assertTrueNo le puede dar tanto detalle como assertEqualso assertThatcuando una prueba falla
Mike Valenty
1
@Michael Seguro que puede. assertTrue("Expected string matching '" +expectedRegex+ "'. Got: "+actual, actual.matches(expectedRegex));. Sin embargo, no es tan agradable como Hamcrest.
MikeFHay
@MikeValenty Si solo está comparando un valor is(true), entonces assertThatno le brinda más detalles que los que lo assertTruehace. Para obtener los mensajes de error adecuados, necesita un comparador diferente (o construye el mensaje manualmente como sugirió @MikeFHay).
ThrawnCA
20

Puede usar Hamcrest, pero debe escribir su propio comparador:

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

uso

import org.junit.Assert;


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

Puede utilizar Hamcrest y jcabi-matchers :

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

Más detalles aquí: Matchers Hamcrest de expresión regular .

Necesitará estas dos dependencias en 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>
yegor256
fuente
Descubrí que la dependencia de hamcrest-core no es necesaria
JohnP2
4

Como también estaba buscando esta funcionalidad, comencé un proyecto en GitHub llamado regex-tester . Es una biblioteca que ayuda a facilitar la prueba de expresiones regulares en Java (actualmente solo funciona con JUnit).

La biblioteca es muy limitada en este momento, pero tiene un comparador Hamcrest que funciona así

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

Más información sobre cómo usar regex-tester está aquí .

Nick A. Watts
fuente
4

Un matcher similar a la aplicación de Ralph ha sido añadido a la biblioteca oficial igualadores de Java Hamcrest. Desafortunadamente, aún no está disponible en un paquete de lanzamiento. Sin embargo, la clase está en GitHub si quieres echarle un vistazo.

Nick A. Watts
fuente
3

Hay un emparejador correspondiente en Hamcrest: org.hamcrest.Matchers.matchesPattern (String regex) .

Como el desarrollo de Hamcrest se detuvo, no puede usar la última versión 1.3 disponible:

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

En su lugar, debe usar una nueva serie de desarrollo (pero aún con fecha de enero de 2015 ):

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

o mejor:

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

En prueba:

Assert.assertThat("123456", Matchers.matchesPattern("^[0-9]+$"));
Gavenkoa
fuente
Recibo el error: Clase duplicada org.hamcrest.BaseDescripción encontrada en los módulos jetified-hamcrest-core-1.3.jar (org.hamcrest: hamcrest-core: 1.3) y jetified-java-hamcrest-2.0.0.0.jar (org.hamcrest : java-hamcrest: 2.0.0.0)
a_subscriber
2

otra alternativa usando assertj. este enfoque es bueno ya que le permite pasar el objeto de patrón directamente.

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


no es JUnit pero aquí hay otra forma con fest-assert:

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