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


75

我似乎在PHPUnit中找不到一个断言,该断言只是测试一个字符串是否包含在另一个字符串的某个位置。尝试做这样的事情:

public function testRecipe() {

    $plaintext = get_bread_recipe();

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

}

我要代替什么真正的主张assertStringContains?在这种情况下,我宁愿不必担心正则表达式,因为绝对不需要它。

如此简单,以至于我必须忽略了某些东西,但我只是想不通!滑稽足够有assertStringStartsWith()assertStringEndsWith()

更新:我知道strpos() !== false可以使用,但我正在寻找更清洁的东西。如果我仍然使用原始的PHP函数,那么所有断言的重点是什么...


没有这样做的方法,但是您可以使用$this->assertGreaterThan(0, strpos($plaintext, 'flour'));
Bartek

1
@bartek如果字符串以'flour'开头将失败
GordonM 2014年

@GordonM对,在这种情况下,-1可以解决问题
Bartek

1
@bartek还是行不通的。你必须为FALSE做了严格的测试
GordonM

6
瞧,这正是我想要该特定断言的原因-此处的混淆已经很明显了!
TheStoryCoder 2014年

Answers:



79

如您所知,assertContains它用于检查数组是否包含值。

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

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

您只需要添加定界符。

如果您确实想要一个assertStringContains断言,则可以扩展PHPUnit_Framework_TestCase并创建自己的断言。

更新

在最新版本的PHPUnit中,assertContains将在字符串上工作。


14
phpunit的最新版本可以执行assertContains字符串。
杰里米·法兰西

5
v9中的更新:assertStringContainsString或assertStringContainsStringIgnoringCase
弗朗索瓦·布列塔尼

2
我们可以用PHPUnit的这些方法:assertStringContainsString()或assertStringContainsStringIgnoringCase()和assertStringNotContainsString()或assertStringNotContainsStringIgnoringCase()顺便说一下注意,assertContains()的字符串草堆被淘汰,并不再PHPUnit中9.支持
FFinn

76

您总是可以将丑陋隐藏在自定义断言方法中,因此基本上我会有一个BaseTestCase类,该类继承自phpunit测试用例,您可以使用该类来拥有自己的可重用断言库(请参阅http://xunitpatterns.com/Custom %20Assertion.html)..(在php 5.4中,您也可以使用特征,imho断言库是特征实际上有用的情况之一)..我总是在我的项目中引入很多自定义断言,通常是特定于领域的。是的,有些也很丑陋:)好吧,我想这就是封装的目的……其中……:)

更新: 我刚刚检查过,“ assertContains”和“ assertNotContains”实际上还对字符串以及数组(以及任何实现“ Traversable”的东西)进行操作:

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

PHPUnit \ Framework \ Exception:PHPUnit \ Framework \ Assert :: assertContains()的参数2(无值)必须是数组,可遍历或字符串
Farid Movsumov

1
此行为已弃用
烤饼

-1

您可以对任何内容进行断言,包括原始的PHP函数。如果断言您对要测试的字符串感兴趣的子字符串的strpos不会返回FALSE,那么它将满足您的需求。

但是请确保您要针对FALSE进行检查,而不是要评估为FALSE的值(例如0)(如果要测试的字符串以给定的子字符串开头,则strpos将返回该值)。


因为您提到的原因,我只想要比使用strpos()更干净的东西!但是我猜它根本不存在。
TheStoryCoder 2014年

-1

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

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

或将其包裹在更整洁的方法中:

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

-2

您不能仅使用可用的简单PHP函数以字符串形式生成字符串,然后使用assertEquals输出该字符串吗?当然,它并不那么闪亮,但是可以工作。

或者,您可以将assertThat与正则表达式一起使用。

从示例的有限角度来看,这听起来似乎是代码/测试设计固有的错误。函数为什么会返回长度未知的复杂字符串,且字符串中应有“某处”?

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


是的,我一直在寻找闪亮的方式来做。我正在测试检索发布变量的网页,因此我想根据该页面中是否存在字符串来测试请求是否正常。我看不出我该怎么做。
TheStoryCoder 2014年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.