Подтвердить что ты не робот

Как проверить, содержит ли строка другую строку в PHPUnit?

Я не могу найти утверждение в PHPUnit, которое просто проверяет, содержится ли строка где-то в другой строке. Попытка сделать что-то вроде этого:

public function testRecipe() {

    $plaintext = get_bread_recipe();

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

}

Какое реальное утверждение я бы поставил вместо assertStringContains? Я бы предпочел не беспокоиться о регулярном выражении в этом случае, потому что в этом нет необходимости.

Это так просто, что должно быть что-то, что я упустил, но я просто не могу понять это! Достаточно смешно, что есть assertStringStartsWith() и assertStringEndsWith()!

Обновление: Я знаю, что strpos() !== false можно использовать, но я ищу что-то более чистое. Если я просто использую ванильные функции PHP, так или иначе, что все указывает на все утверждения, тогда...

4b9b3361

Ответ 1

Как вы могли бы сказать, assertContains предназначен для проверки того, что массив содержит значение.

Если посмотреть, содержит ли строка подстроку, самым простым запросом будет использование assertRegexp()

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

Вам просто нужно добавить разделители.

Если вы действительно хотите иметь утверждение assertStringContains, вы можете расширить PHPUnit_Framework_TestCase и создать свой собственный.

UPDATE

В последней версии PHPUnit assertContains будет работать с строками.

Ответ 2

Вы всегда можете скрыть уродство внутри настраиваемого метода утверждения, поэтому в основном у меня был бы класс BaseTestCase, который наследуется от тестового примера phpunit, который вы могли бы использовать, чтобы иметь свою собственную библиотеку повторных утверждений (см. http://xunitpatterns.com/Custom%20Assertion.html).. (В php 5.4 вы также можете использовать черты, библиотеки подтверждения imho - это один из тех случаев, когда на самом деле полезны черты). Я всегда представляю вполне несколько пользовательских утверждений в моих проектах, часто специфичных для домена. И да, некоторые тоже уродливые:) ну, я думаю, что инкапсуляция существует для... Среди вещей...:)

UPDATE: Я просто проверил и "assertContains" и "assertNotContains" на самом деле также работает с строками, а также с массивами (и с любым, что реализует "Traversable" ):

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

Ответ 3

Не можете ли вы просто сделать строку в строке, используя доступные функции PHP, а затем assertEquals - вывод этого? Конечно, это не так блестяще, но оно работает.

В качестве альтернативы вы можете использовать assertThat с регулярным выражением.

Похоже, что что-то по своей сути ошибочно относится к дизайну кода/теста, хотя, с ограниченной перспективы этого примера. Почему функция возвращает сложную строку неизвестной длины с ожидаемым битом "где-то" в строке?

В тесте вы должны иметь возможность контролировать свой вход, поэтому вы должны знать всю свою ожидаемую строку вывода. Если ваша функция разрушает другие части строки, это утверждение не сообщит вам об этом. Вероятно, поэтому функция assertStringContains не существует.

Ответ 4

Вы можете делать утверждения против чего угодно, включая ванильные функции PHP. Если вы утверждаете, что strpos для подстроки, которая вас интересует в тестируемой строке, не возвращает FALSE, она будет соответствовать вашим потребностям.

Убедитесь, что вы проверяете FALSE, но не то, что оценивает FALSE, например 0 (это то, что strpos будет возвращать, если тестируемая строка начинается с данной подстроки).

Ответ 5

Расширяясь от @Schleis, если у вас более сложные строки, вам нужно будет избежать регулярного выражения:

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

Или оберните его более аккуратным способом:

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

Ответ 6

if (strpos($plaintext, 'flour') === false){
   $this->fail("planintext should contain 'flour'");
}