嘲弄 shouldReceive()->once() 似乎不起作用

Posted

技术标签:

【中文标题】嘲弄 shouldReceive()->once() 似乎不起作用【英文标题】:Mockery shouldReceive()->once() doesn't seem to work 【发布时间】:2013-04-08 18:28:28 【问题描述】:

我试图让 Mockery 断言给定方法至少被调用一次。

我的测试课是:

use \Mockery as m;

class MyTest extends \phpUnit_Framework_TestCase


    public function testSetUriIsCalled()
    
        $uri = 'http://localhost';
        $httpClient = m::mock('Zend\Http\Client');
        $httpClient->shouldReceive('setUri')->with($uri)->atLeast()->once();
    


如您所见,有一个测试(希望)创建了 setUri 将被调用的期望。由于没有涉及任何其他代码,我无法想象它可以被调用而我的测试通过了。谁能解释一下为什么?

【问题讨论】:

【参考方案1】:

您需要致电Mockery:close() 来验证您的期望。它还为下一个测试用例处理 mockery 容器的清理。

public function tearDown()

    parent::tearDown();
    m::close();

【讨论】:

【参考方案2】:

为了避免在每个测试类中调用 close 方法,您可以像这样将 TestListener 添加到您的 phpunit 配置中:

<listeners>
    <listener class="\Mockery\Adapter\Phpunit\TestListener"></listener>
</listeners>

docs 中解释了这种方法。

链接文档中需要注意的一点是:

确保引导文件中存在 Composer 或 Mockery 的自动加载器,否则您还需要定义指向上述 TestListener 类文件的“文件”属性。

【讨论】:

PHPUnit 7 不再支持此功能【参考方案3】:

只是一个旁注:如果你使用 Laravel:make:test --unit 生成一个测试类,它扩展了原始的 PhpUnit Testcase 类而不是包含的 Tests\Testcase,它加载 laravel 应用程序并运行 Mockery::close ()。这也是在某些情况下,如果您在测试单元中使用 Laravel 特定代码(如缓存、数据库或存储),您的测试会失败的原因。

因此,如果您需要使用 Laravel 特定代码测试单元,只需更换“扩展测试用例”即可,无需手动调用 Mockery::close()

【讨论】:

以上是关于嘲弄 shouldReceive()->once() 似乎不起作用的主要内容,如果未能解决你的问题,请参考以下文章

嘲弄“with”方法没有显示失败的原因

嘲弄和method_exists

用嘲弄来测试 Laravel 外观总是通过,即使它应该失败

嘲弄“应该接收”但方法不存在

mockery->shouldReceive() 啥时候不应该通过?

stringContains 参数匹配 Laravel Log 门面 shouldReceive