使用 Mockery 模拟在另一个静态方法中调用的静态方法

Posted

技术标签:

【中文标题】使用 Mockery 模拟在另一个静态方法中调用的静态方法【英文标题】:Use Mockery to mock a static method called in another static method 【发布时间】:2016-06-24 23:18:29 【问题描述】:

我想用 Mokcery 模拟一个已经在另一个方法中使用过的静态方法,如下:

Class SomeClass

   public static function methodA()
   
     .....;
     self::B();
    
   public static function methodB()
   
     Do SomeThing
   

如果我想mock methodB,并使用methodA,mock函数不起作用,因为methodB用在methodA中,如下

 use Mockery as m;
   $mocktest = m::mock->('SomeClass[B]');
   $mocktest->shouldReceive('B')->andReturn("expectedResult");
   $mocktest->methodA();

上面的代码将导致methodB仍然返回它的原始结果而不是'expectedResult'。 我希望methodA中使用的methodB被嘲笑,我该如何操作?

【问题讨论】:

【参考方案1】:

您需要使用别名来模拟静态方法:

$mock = \Mockery::mock('alias:SomeClass');

请注意,类还不能加载。否则嘲讽将无法为它起别名。

文档中的更多内容:

Mocking Public Static Methods Quick Reference

请注意,模拟静态方法不是一个好主意。如果你觉得你需要它,那么你的设计就有问题。 嘲笑你正在测试的班级更糟糕,这表明你的班级有太多的责任。

【讨论】:

感谢您的帮助。但我现在要做的是模拟一个已在另一个静态方法中调用的静态方法,而不仅仅是模拟一个简单的静态方法。 在我的例子中,为了使测试成为可能,我围绕 Laravel 作业调度调用创建了一个非静态包装器函数(然后包装器是可模拟的):public function dispatchCustomMailableJob($contactId, $executeAt, $customMailable) SendEmailJob::dispatch($contactId, $executeAt, $customMailable);

以上是关于使用 Mockery 模拟在另一个静态方法中调用的静态方法的主要内容,如果未能解决你的问题,请参考以下文章

PHP 单元测试 - 使用 Mockery 模拟静态自动加载类

嘲弄:模拟对象上不存在方法

在 Mockery 中测试链式方法调用

如何模拟 Laravel Eloquent 模型的静态方法?

自称 PhpUnit / Mockery 的模拟方法

模拟静态 Eloquent 模型方法,包括 find()