如何在PHPUnit中测试字符串是否包含另一个字符串


How to test if string contains another string in PHPUnit?

我似乎找不到一个断言在PHPUnit,简单地测试一个字符串是否包含在另一个字符串的某个地方。试着做这样的事情:

public function testRecipe() {
    $plaintext = get_bread_recipe();
    $this->assertStringContains('flour', $plaintext);
}

我应该用什么真实的断言来代替assertStringContains ?在这种情况下,我宁愿不用担心正则表达式,因为绝对不需要它。

这么简单,一定是我忽略了什么,但我就是想不出来!有趣的是,有assertStringStartsWith()assertStringEndsWith() !

更新:我知道strpos() !== false可以使用,但我正在寻找更干净的东西。如果我只是使用普通的PHP函数那么这些断言有什么意义呢然后。

可以看出assertContains是用来检查数组是否包含值的

查看字符串是否包含子字符串,最简单的查询是使用assertRegexp()

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

您只需要添加分隔符。

如果你真的想要一个assertStringContains断言,你可以扩展PHPUnit_Framework_TestCase并创建你自己的。

在PHPUnit 9之前的版本中,assertContains可以处理字符串。

9+我们需要使用assertStringContainsStringassertStringContainsStringIgnoringCase

你总是可以在自定义断言方法中隐藏丑陋,所以基本上我会有一个继承自phpunit测试用例的BaseTestCase类,你可以使用它来拥有你自己的可重用断言库(参见http://xunitpatterns.com/Custom%20Assertion.html)..(在php 5.4中,你也可以使用trait,尽管断言库是trait实际有用的情况之一)..我总是在我的项目中引入相当多的定制断言,通常是特定于领域的。是的,有些也很丑:)好吧,我想这就是封装的作用……在…的东西:)

更新:我刚刚检查和'assertContains'和'assertNotContains'实际上也操作字符串以及数组(和任何实现'可遍历'):

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

2019+和PHPUnit 8.0+更新

assertContains()自PHPUnit 8.0起已弃用,请参阅问题#3425。


现在推荐具体方法(见issue #3422):

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

提示:立即升级与Rector和PHPUnit 8.0集。

可以对任何东西进行断言,包括普通的PHP函数。如果您断言您感兴趣的子字符串的strpos在您正在测试的字符串上不返回FALSE,那么它将满足您的需求。

请确保您检查的是FALSE,而不是计算结果为FALSE的东西,例如0(如果要测试的字符串以给定的子字符串开头,strpos将返回0)。

从@Schleis扩展,如果您有更复杂的字符串,则需要转义正则表达式:

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

或者用更简洁的方法包装:

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

你不能使用普通的PHP函数在字符串中做字符串,然后asserequals输出吗?当然,它没有那么闪亮,但它有效。

或者你可以使用assertThat和正则表达式。

从这个例子的有限角度来看,这听起来像是代码/测试的设计本身就有问题。为什么一个函数会返回一个未知长度的复杂字符串,在字符串中有预期的"某处"位?

在测试中,您应该能够控制您的输入,因此您应该知道您的整个预期输出字符串。如果你的函数破坏了字符串的其他部分,这个断言是不会告诉你的。这可能就是assertStringContains函数不存在的原因。