我似乎找不到一个断言在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+我们需要使用assertStringContainsString
或assertStringContainsStringIgnoringCase
你总是可以在自定义断言方法中隐藏丑陋,所以基本上我会有一个继承自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函数不存在的原因。