我似乎无法在PHPUnit中找到一个断言,只是测试字符串是否包含在另一个字符串中的某个位置。试着做这样的事情:
public function testRecipe() {
$plaintext = get_bread_recipe();
$this->assertStringContains('flour', $plaintext);
}
我会用什么真正的断言代替assertStringContains
?在这种情况下,我宁愿不必担心正则表达式,因为完全不需要它。
这很简单,必须有一些我忽略的东西,但我无法弄清楚!有趣的是assertStringStartsWith()
和assertStringEndsWith()
!
更新:我知道可以使用strpos() !== false
,但我正在寻找更清洁的东西。如果我只是使用vanilla PHP函数,那么所有断言的重点是什么......
答案 0 :(得分:72)
你总是可以隐藏自定义断言方法中的丑陋,所以基本上我会有一个继承自phpunit测试用例的BaseTestCase类,你可以使用它来拥有自己的可重用断言库(参见http://xunitpatterns.com/Custom%20Assertion.html) ..(在PHP 5.4中你也可以使用特征,imho断言库是特征实际上有用的案例之一)。我总是在我的项目中引入相当多的自定义断言,通常是特定于域的。是的,有些也很难看:)好吧,我想那是什么封装......其中......:)
<强>更新强> 我刚检查过并且断言包含&#39;并且&#39;断言不包含&#39;实际上也可以操作字符串和数组(以及实现&#39; Traversable&#39;)的所有内容:
function test_Contains()
{
$this->assertContains("test", "this is a test string" );
$this->assertNotContains("tst", "this is a test string");
}
答案 1 :(得分:61)
正如您所知,assertContains
用于检查数组是否包含值。
查看字符串是否包含子字符串,您最简单的查询是使用assertRegexp()
$this->assertRegexp('/flour/', $plaintext);
您只需要添加分隔符。
如果您真的想要assertStringContains
断言,可以延长PHPUnit_Framework_TestCase
并创建自己的声明。
<强>更新强>
在最新版本的PHPUnit中,assertContains
将用于字符串。
答案 2 :(得分:0)
你不能只使用可用的普通PHP函数在字符串中执行字符串,然后assertEquals输出吗?当然,它没有那么闪亮,但它确实有效。
或者,您可以将assertThat与正则表达式一起使用。
虽然从示例的有限角度来看,代码/测试的设计本身就是错误的。为什么函数会返回一个未知长度的复杂字符串,字符串中的预期位“某处”?
在测试中,您应该能够控制输入,因此您应该知道整个预期的输出字符串。如果你的函数破坏了字符串的其他部分,那么这个断言就不会告诉你它。这可能是assertStringContains函数不存在的原因。
答案 3 :(得分:0)
你可以对任何东西做断言,包括vanilla PHP函数。如果你声明你对你正在测试的字符串感兴趣的子字符串的strpos没有返回FALSE它将满足你的需求。
请确保您正在检查FALSE,而不是评估为FALSE的内容,例如0(如果正在测试的字符串以给定的子字符串开头,那么strpos将返回)。
答案 4 :(得分:0)
从@Schleis扩展,如果你有更复杂的字符串,你将需要逃避正则表达式:
$this->assertRegexp('/' . preg_quote('[some $stuff]') . '/', $plaintext);
或者用更简洁的方法将其包起来:
public function assertStringContains($needle, $haystack)
{
$this->assertRegexp('/' . preg_quote($needle) . '/', $haystack);
}
答案 5 :(得分:0)
assertContains()
,请参见issue #3425。
现在建议使用特定方法(请参见issue #3422
)
$this->assertStringContainsString('flour', $plaintext);
答案 6 :(得分:-1)
if (strpos($plaintext, 'flour') === false){
$this->fail("planintext should contain 'flour'");
}