Wie teste ich, ob der String einen anderen String in PHPUnit enthält?

Lesezeit: 5 Minuten

Benutzer-Avatar
TheStoryCoder

Ich kann anscheinend keine Behauptung darin finden PHPUnit das testet einfach, ob ein String irgendwo in einem anderen String enthalten ist. Versuche so etwas zu machen:

public function testRecipe() {

    $plaintext = get_bread_recipe();

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

}

Welche echte Behauptung würde ich stattdessen setzen assertStringContains ? Ich würde es vorziehen, mich in diesem Fall nicht um Regex kümmern zu müssen, da dies absolut nicht erforderlich ist.

Es ist so einfach, dass ich etwas übersehen haben muss, aber ich kann es einfach nicht herausfinden! Komischerweise gibt es das assertStringStartsWith() und assertStringEndsWith()!

Aktualisieren: Ich weiss strpos() !== false könnte verwendet werden, aber ich suche etwas saubereres. Wenn ich sowieso nur Vanilla-PHP-Funktionen verwende, was ist dann der springende Punkt mit all den Behauptungen …

  • Es gibt keine solche Methode, aber Sie können sie verwenden $this->assertGreaterThan(0, strpos($plaintext, 'flour'));

    – Bartek

    3. Juni 2014 um 13:14 Uhr


  • @bartek Das wird fehlschlagen, wenn die Zeichenfolge mit ‘Mehl’ beginnt

    – GordonM

    3. Juni 2014 um 13:20 Uhr

  • @GordonM Richtig, in diesem Fall -1 wird den Trick machen

    – Bartek

    3. Juni 2014 um 13:22 Uhr

  • @bartek Das wird immer noch nicht funktionieren. Sie müssen einen strengen Test für FALSCH durchführen

    – GordonM

    3. Juni 2014 um 13:23 Uhr

  • Sehen Sie, genau deshalb wollte ich diese spezifische Behauptung – die Verwirrung ist hier bereits offensichtlich!

    – TheStoryCoder

    3. Juni 2014 um 13:48 Uhr

Benutzer-Avatar
Schleis

Wie Sie sehen konnten assertContains dient zum Prüfen, ob ein Array einen Wert enthält.

Um zu sehen, ob die Zeichenfolge eine Teilzeichenfolge enthält, wäre Ihre einfachste Abfrage zu verwenden behauptenRegexp()

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

Sie müssten nur die Trennzeichen hinzufügen.

Wenn du wirklich eine haben willst assertStringContains Behauptung, können Sie erweitern PHPUnit_Framework_TestCase und erstellen Sie Ihre eigenen.

AKTUALISIEREN

In der neuesten Version von PHPUnit, assertContains funktioniert auf Saiten.

  • Neuere Versionen von phpunit können eine assertContains-Zeichenfolge ausführen.

    – Jeremy French

    26. September 2014 um 14:21 Uhr

  • Update in v9: assertStringContainsString oder assertStringContainsStringIgnoringCase

    – Francois Breton

    22. Mai 2019 um 16:03 Uhr

  • Wir können diese Methoden von PHPUnit verwenden: assertStringContainsString() oder assertStringContainsStringIgnoringCase() UND assertStringNotContainsString() oder assertStringNotContainsStringIgnoringCase() Beachten Sie übrigens, dass assertContains() mit String-Heuhaufen veraltet ist und in PHPUnit 9 nicht unterstützt wird.

    – FFinn

    29. November 2019 um 10:39 Uhr


  • @schleis UPDATE assertContains funktioniert nicht mehr auf String (9.5.20) Musste `assertTrue(str_contains(…̀

    – St3an

    29. April um 6:56 Uhr

Benutzer-Avatar
malte

Sie können die Hässlichkeit immer in einer benutzerdefinierten Assertion-Methode verbergen, also hätte ich im Grunde eine BaseTestCase-Klasse, die vom phpunit-Testfall erbt, die Sie verwenden könnten, um Ihre eigene Bibliothek wiederverwendbarer Assertionen zu haben (siehe http://xunitpatterns.com/Custom%20Assertion.html).. (In PHP 5.4 können Sie auch Traits verwenden, meiner Meinung nach sind Assertionsbibliotheken einer der Fälle, in denen Traits tatsächlich nützlich sind).. Ich füge immer einige benutzerdefinierte Assertionen in meine Projekte ein, oft domänenspezifisch. Und ja, manche sind auch hässlich 🙂 Nun, ich denke, dafür ist die Kapselung da … Unter anderem … 🙂

AKTUALISIEREN:
Ich habe gerade nachgesehen und ‘assertContains’ und ‘assertNotContains’ arbeiten tatsächlich auch mit Strings sowie Arrays (und allem, was ‘Traversable’ implementiert):

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

  • PHPUnit\Framework\Exception: Argument Nr. 2 (kein Wert) von PHPUnit\Framework\Assert::assertContains() muss ein Array, durchquerbar oder ein String sein

    – Farid Movsumov

    4. November 2017 um 21:23 Uhr

  • Dieses Verhalten ist veraltet

    – Scones

    25. Februar 2019 um 14:05 Uhr

  • War 2015 in Ordnung, aber unter PHP 8.1 wirft einen fatalen Fehler: TypeError: PHPUnit\Framework\Assert::assertContains(): Argument #2 ($haystack) must be of type iterable, string given. Wir können zu assertStringContainsString migrieren.

    – Dereckson

    12. März um 14:09 Uhr

Benutzer-Avatar
Tomás Votruba

2019 und PHPUnit 8.0-Update

assertContains() ist seit PHPUnit 8.0 veraltet, siehe Ausgabe Nr. 3425.

Nun wird die spezifische Methode empfohlen (vgl issue #3422):

$plaintext="I fell on the flour";
$this->assertStringContainsString('flour', $plaintext);

TIPP: Upgrade sofort mit Rector und PHPUnit 8.0 eingestellt.

  • Klare Antwort, auf den Punkt gebracht und auf die neueste Version aktualisiert. Dies ist die gültige Antwort für mich. Ich sehe andere Antworten mit höherer Punktzahl, aber wenn das Framework dafür eine bestimmte Methode hat, sehe ich nicht, warum Problemumgehungen wie “assertRegexp” verwendet werden sollten.

    – Miquel-Kanal

    27. Januar 2021 um 10:51 Uhr

  • Problemumgehungen waren für ältere Versionen. Dies ist die richtige Antwort für PHPUnit 8+.

    – Mat Lipe

    8. Dezember 2021 um 16:08 Uhr

Sie können Behauptungen gegen alles Mögliche machen, einschließlich Vanilla-PHP-Funktionen. Wenn Sie behaupten, dass strpos für den Teilstring, an dem Sie interessiert sind, auf dem String, den Sie testen, nicht FALSE zurückgibt, wird es Ihren Anforderungen entsprechen.

Stellen Sie jedoch sicher, dass Sie gegen FALSE prüfen und nicht gegen etwas, das FALSE ergibt, wie z. B. 0 (was strpos zurückgibt, wenn die zu testende Zeichenfolge mit der angegebenen Teilzeichenfolge beginnt).

Ausgehend von @Schleis müssen Sie, wenn Sie kompliziertere Zeichenfolgen haben, die Regex maskieren:

$this->assertRegexp("https://stackoverflow.com/" . preg_quote('[some $stuff]') . "https://stackoverflow.com/", $plaintext);

Oder packen Sie es auf eine ordentlichere Weise ein:

public function assertStringContains($needle, $haystack)
{
    $this->assertRegexp("https://stackoverflow.com/" . preg_quote($needle) . "https://stackoverflow.com/", $haystack);
}

Benutzer-Avatar
Einsiedleraffe

Können Sie nicht einfach die Zeichenfolge in Zeichenfolge mit den verfügbaren einfachen PHP-Funktionen ausführen und dann die Ausgabe davon behaupten? Zugegeben, es ist nicht so glänzend, aber es funktioniert.

Alternativ können Sie assertThat mit einem regulären Ausdruck verwenden.

Aus der begrenzten Perspektive des Beispiels klingt es jedoch so, als ob etwas mit dem Design des Codes / Tests von Natur aus falsch ist. Warum würde eine Funktion einen komplexen String unbekannter Länge zurückgeben, mit dem erwarteten Bit „irgendwo“ im String?

Im Test sollten Sie in der Lage sein, Ihre Eingabe zu kontrollieren, also sollten Sie Ihren gesamten erwarteten Ausgabestring kennen. Wenn Ihre Funktion andere Teile der Zeichenfolge ruiniert, würde Ihnen diese Behauptung nichts darüber sagen. Das ist wahrscheinlich der Grund, warum die Funktion assertStringContains nicht existiert.

1354220cookie-checkWie teste ich, ob der String einen anderen String in PHPUnit enthält?

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy