¿Cómo probar si la cadena contiene otra cadena en PHPUnit?
⏰ 5 minutos de lectura
El codificador de historias
Parece que no puedo encontrar una afirmación en Unidad PHP que simplemente prueba si una cadena está contenida en algún lugar de otra cadena. Tratando de hacer algo como esto:
public function testRecipe() {
$plaintext = get_bread_recipe();
$this->assertStringContains('flour', $plaintext);
}
¿Qué afirmación real pondría en lugar de assertStringContains ? Preferiría no tener que preocuparme por las expresiones regulares en este caso porque no hay absolutamente ninguna necesidad de ello.
Es tan simple que debe haber algo que he pasado por alto, ¡pero simplemente no puedo resolverlo! Bastante gracioso que hay assertStringStartsWith() y assertStringEndsWith()!
Actualizar: lo sé strpos() !== false podría usarse pero estoy buscando algo más limpio. Si solo uso las funciones de PHP de vainilla de todos modos, ¿cuál es el punto con todas las afirmaciones entonces …
No existe tal método para hacer eso, sin embargo, puede usar $this->assertGreaterThan(0, strpos($plaintext, 'flour'));
– Bartek
3 de junio de 2014 a las 13:14
@bartek Eso fallará si la cadena comienza con ‘harina’
– GordonM
3 de junio de 2014 a las 13:20
@GordonM Correcto, en este caso -1 hará el truco
– Bartek
3 de junio de 2014 a las 13:22
@bartek Eso todavía no funcionará. Tienes que hacer una prueba estricta para FALSO
– GordonM
3 de junio de 2014 a las 13:23
Mira, esto es exactamente por lo que quería esa afirmación específica: ¡la confusión ya es evidente aquí!
– TheStoryCoder
3 de junio de 2014 a las 13:48
Schleis
como podrías decir assertContains es para comprobar que una matriz contiene un valor.
Mirando para ver si la cadena contiene una subcadena, su consulta más simple sería usar afirmarRegexp()
$this->assertRegexp('/flour/', $plaintext);
Solo necesitaría agregar los delimitadores.
Si realmente quieres tener un assertStringContains afirmación, puede extender PHPUnit_Framework_TestCase y crea el tuyo propio.
ACTUALIZAR
En la última versión de PHPUnit, assertContains funcionará en cuerdas.
Las versiones más recientes de phpunit pueden hacer assertContains string.
– Jeremy francés
26/09/2014 a las 14:21
Actualización en v9: assertStringContainsString o assertStringContainsStringIgnoringCase
– François Bretón
22 de mayo de 2019 a las 16:03
Podemos usar estos métodos de PHPUnit: assertStringContainsString() o assertStringContainsStringIgnoringCase() Y assertStringNotContainsString() o assertStringNotContainsStringIgnoringCase() Por cierto, tenga en cuenta que assertContains() con pajares de cadena está obsoleto y no será compatible con PHPUnit 9.
– Finn
29 de noviembre de 2019 a las 10:39
@schleis ACTUALIZAR asertContains ya no funciona en cadenas (9.5.20) Tuve que usar `assertTrue(str_contains(…̀
– St3an
29 abr a las 6:56
malta
Siempre puede ocultar la fealdad dentro de un método de aserción personalizado, por lo que básicamente tendría una clase BaseTestCase que hereda del caso de prueba phpunit que podría usar para tener su propia biblioteca de aserciones reutilizables (ver http://xunitpatterns.com/Custom%20Assertion.html).. (En php 5.4 también puede usar rasgos, en mi humilde opinión, las bibliotecas de aserciones son uno de los casos en los que los rasgos son realmente útiles). Siempre introduzco bastantes aserciones personalizadas en mis proyectos, a menudo específicas del dominio. Y sí, algunos también son feos 🙂 bueno, supongo que para eso está la encapsulación… Entre otras cosas… 🙂
ACTUALIZAR:
Acabo de verificar y ‘assertContains’ y ‘assertNotContains’ en realidad también operan en cadenas y matrices (y cualquier cosa que implemente ‘Traversable’):
function test_Contains()
{
$this->assertContains("test", "this is a test string" );
$this->assertNotContains("tst", "this is a test string");
}
PHPUnit\Framework\Exception: el argumento n.º 2 (sin valor) de PHPUnit\Framework\Assert::assertContains() debe ser una matriz, transitable o una cadena
– Farid Movsumov
4 de noviembre de 2017 a las 21:23
este comportamiento está en desuso
– bollos
25 de febrero de 2019 a las 14:05
Estaba bien en 2015 pero bajo PHP 8.1 arroja un error fatal: TypeError: PHPUnit\Framework\Assert::assertContains(): Argument #2 ($haystack) must be of type iterable, string given. Podemos migrar a assertStringContainsString.
– Dereckson
12 de marzo a las 14:09
Tomás Votruba
2019 y actualización de PHPUnit 8.0
assertContains() está en desuso desde PHPUnit 8.0, consulte número 3425.
Ahora se recomienda el método específico (ver issue #3422):
$plaintext="I fell on the flour";
$this->assertStringContainsString('flour', $plaintext);
Respuesta clara, al grano y actualizada a la última versión. Esta es la respuesta válida para mí. Veo otras respuestas con una puntuación más alta, pero si el marco tiene un método específico para esto, no veo por qué usar soluciones alternativas como “assertRegexp”.
–Miquel Canal
27 de enero de 2021 a las 10:51
Las soluciones alternativas eran para versiones anteriores. Esta es la respuesta correcta para PHPUnit 8+.
– Mat Lipe
8 dic 2021 a las 16:08
Puede hacer afirmaciones contra cualquier cosa, incluidas las funciones básicas de PHP. Si afirma que strpos para la subcadena que le interesa en la cadena que está probando no devuelve FALSO, satisfará sus necesidades.
Sin embargo, asegúrese de verificar FALSO, y no algo que se evalúe como FALSO, como 0 (que es lo que devolverá strpos si la cadena que se está probando comienza con la subcadena dada).
Extendiendo desde @Schleis, si tiene cadenas más complicadas, deberá escapar de la expresión regular:
public function assertStringContains($needle, $haystack)
{
$this->assertRegexp("https://stackoverflow.com/" . preg_quote($needle) . "https://stackoverflow.com/", $haystack);
}
ermitañocodemonkey
¿No puedes simplemente hacer la cadena en cadena usando las funciones simples de PHP disponibles, y luego afirmar que es igual a la salida de eso? De acuerdo, no es tan brillante, pero funciona.
Alternativamente, puede usar assertThat con una expresión regular.
Sin embargo, parece que algo está intrínsecamente mal con el diseño del código/prueba, desde la perspectiva limitada del ejemplo. ¿Por qué una función devolvería una cadena compleja de longitud desconocida, con el bit esperado ‘en algún lugar’ de la cadena?
En la prueba, debe poder controlar su entrada, por lo que debe conocer toda la cadena de salida esperada. Si su función arruina otras partes de la cadena, solo esta afirmación no le informará al respecto. Probablemente por eso no existe la función assertStringContains.
¿Ha sido útil esta solución?
Tu feedback nos ayuda a saber si la solución es correcta y está funcionando. De esta manera podemos revisar y corregir el contenido.
Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos.
Configurar y más información
No existe tal método para hacer eso, sin embargo, puede usar
$this->assertGreaterThan(0, strpos($plaintext, 'flour'));
– Bartek
3 de junio de 2014 a las 13:14
@bartek Eso fallará si la cadena comienza con ‘harina’
– GordonM
3 de junio de 2014 a las 13:20
@GordonM Correcto, en este caso
-1
hará el truco– Bartek
3 de junio de 2014 a las 13:22
@bartek Eso todavía no funcionará. Tienes que hacer una prueba estricta para FALSO
– GordonM
3 de junio de 2014 a las 13:23
Mira, esto es exactamente por lo que quería esa afirmación específica: ¡la confusión ya es evidente aquí!
– TheStoryCoder
3 de junio de 2014 a las 13:48