web-dev-qa-db-fra.com

Comment tester si une chaîne contient une autre chaîne dans PHPUnit?

Je n'arrive pas à trouver une assertion dans PHPUnit qui teste simplement si une chaîne est contenue quelque part dans une autre chaîne. Essayer de faire quelque chose comme ça:

public function testRecipe() {

    $plaintext = get_bread_recipe();

    $this->assertStringContains('flour', $plaintext);

}

Quelle assertion réelle devrais-je mettre à la place de assertStringContains? Je préférerais ne pas avoir à me soucier des regex dans ce cas car il n'y en a absolument pas besoin.

C'est si simple qu'il doit y avoir quelque chose que j'ai oublié, mais je n'arrive pas à le comprendre! Assez drôle, il y a assertStringStartsWith() et assertStringEndsWith()!

Mise à jour: Je sais que strpos() !== false pourrait être utilisé mais je cherche quelque chose de plus propre. Si j'utilise juste Vanilla PHP fonctionne de toute façon quel est le point avec toutes les affirmations alors ...

57
TheStoryCoder

Comme vous pouvez le voir, assertContains sert à vérifier qu'un tableau contient une valeur.

Si vous cherchez à voir si la chaîne contient une sous-chaîne, votre requête la plus simple serait d'utiliser assertRegexp ()

$this->assertRegexp('/flour/', $plaintext);

Vous auriez juste besoin d'ajouter les délimiteurs.

Si vous voulez vraiment avoir une assertion assertStringContains, vous pouvez étendre PHPUnit_Framework_TestCase et créez le vôtre.

[~ # ~] mise à jour [~ # ~]

Dans la dernière version de PHPUnit, assertContains fonctionnera sur les chaînes.

64
Schleis

Vous pouvez toujours masquer la laideur à l'intérieur d'une méthode d'assertion personnalisée, donc en gros, j'aurais une classe BaseTestCase qui hérite du scénario de test phpunit que vous pourriez utiliser pour avoir votre propre bibliothèque d'assertions réutilisables (voir http: // xunitpatterns .com/Custom% 20Assertion.html ) .. (Dans php 5.4, vous pouvez également utiliser des traits, les bibliothèques d'assertions imho sont l'un des cas où les traits sont réellement utiles) .. J'introduis toujours pas mal d'assertions personnalisées dans mes projets, souvent spécifiques à un domaine. Et oui, certains sont moche aussi :) eh bien, je suppose que c'est pour ça que l'encapsulation est là ... Entre autres choses ... :)

MISE À JOUR: Je viens de vérifier et 'assertContains' et 'assertNotContains' fonctionnent également sur les chaînes ainsi que sur les tableaux (et tout ce qui implémente 'Traversable'):

function test_Contains()
{
    $this->assertContains("test", "this is a test string" );
    $this->assertNotContains("tst", "this is a test string");
}
73
malte

Ne pouvez-vous pas simplement faire la chaîne en chaîne en utilisant les fonctions simples PHP disponibles, puis assertEquals la sortie de cela? Certes, ce n'est pas aussi brillant, mais cela fonctionne.

Vous pouvez également utiliser assertThat avec une expression régulière.

Il semble que quelque chose soit intrinsèquement incorrect dans la conception du code/test, du point de vue limité de l'exemple. Pourquoi une fonction retournerait-elle une chaîne complexe de longueur inconnue, avec le bit attendu "quelque part" dans la chaîne?

Dans le test, vous devriez pouvoir contrôler votre entrée, vous devez donc connaître l'intégralité de votre chaîne de sortie attendue. Si votre fonction ruine d'autres parties de la chaîne, cette affirmation ne vous en parlera pas. C'est probablement pourquoi la fonction assertStringContains n'existe pas.

0
hermitcodemonkey

Mise à jour 2019 et PHPUnit 8.0

assertContains() est obsolète depuis PHPUnit 8.0, voir problème # 3425 .


Maintenant, la méthode spécifique est recommandée (voir issue #3422 ):

$this->assertStringContainsString('flour', $plaintext);
0
Tomáš Votruba

Vous pouvez effectuer des assertions contre tout, y compris Vanilla PHP fonctions. Si vous affirmez que la strpos pour la sous-chaîne qui vous intéresse sur la chaîne que vous testez ne renvoie pas FAUX, elle répondra à votre Besoins.

Assurez-vous cependant que vous vérifiez contre FALSE, et non quelque chose qui est évalué à FALSE tel que 0 (qui est ce que strpos renverra si la chaîne en cours de test commence par la sous-chaîne donnée).

0
GordonM

Dans le prolongement de @Schleis, si vous avez des chaînes plus compliquées, vous devrez échapper à l'expression régulière:

$this->assertRegexp('/' . preg_quote('[some $stuff]') . '/', $plaintext);

Ou enveloppez-le d'une manière plus soignée:

public function assertStringContains($needle, $haystack)
{
    $this->assertRegexp('/' . preg_quote($needle) . '/', $haystack);
}
0
Elliot Chance