在 Laravel 4 中使用 Mockery 模拟自定义类
Posted
技术标签:
【中文标题】在 Laravel 4 中使用 Mockery 模拟自定义类【英文标题】:Mocking a custom class with Mockery in Laravel 4 【发布时间】:2014-12-04 17:02:02 【问题描述】:使用 Laravel 4.2,我在 /app/libraries
中有一个自定义类 TestyClass
。
使用 Mockery 和 phpUnit,我试图模拟这个类,但我的 Mock 似乎没有注册。
当我运行测试时,我得到Mockery\Exception\InvalidCountException: Method testymethod() from Mockery_0_TestyClass should be called exactly 1 times but called 0 times.
我正在测试的控制器运行 TestyClass::testymethod();
,testymethod()
内部的 Log::info 运行正常。
在 Laravel 4.2 中注册自定义类的 Mock 缺少什么?
$mock = Mockery::mock('TestyClass');
$mock->shouldReceive('testymethod')->once();
TestyClass:
class TestyClass
public static function testymethod()
Log::info('----=-=-=-=--=in heyhey!@!!=-=-=-=-=-=-=-12312312312312341');
return true;
【问题讨论】:
【参考方案1】:这段代码:
$mock = Mockery::mock('TestyClass');
创建一个扩展TestyClass
的新类,添加模拟等所需的行为,然后创建它的实例并返回它,因此$mock是Mockery_0_TestyClass
的实例
然后你告诉 mocky 你希望 instance 收到对 testymethod
的调用,但实际上你是在对 TestyClass
类方法进行静态调用。您可以通过嘲弄来做到这一点,但这不是很好,我不建议您这样做,您可能希望在进程隔离的情况下运行测试。
$mock = Mockery::mock('alias:TestyClass');
【讨论】:
是的,就像你说的不是很好,alias
为我的虚拟 TestyClass 工作,但当应用于我真实而广泛的 Lib
类时,它坏了:PHP Fatal error: Call to a member function __call() on a non-object in /Users/lukeshaheen/Dropbox/WWW/Phone2Action 2.0/vendor/mockery/mockery/library/Mockery/Loader/EvalLoader.php(16) : eval()'d code on line 633
。 【参考方案2】:
你在打电话给你的控制器吗?
测试类方法和测试控制器是有区别的。
如果您正在测试控制器,请尝试使用$this->call
- 示例;
class TestyClassTest extends TestCase
public function setUp()
$this->mock = $this->mock('TestyClass');
/* Move method to TestCase.php */
public function mock($class)
$mock = Mockery::mock($class);
$this->app->instance($class, $mock);
return $mock;
/* Move method to TestCase.php */
public function tearDown()
Mockery::close();
public function testIfTestyControllerRunsTestyMethodAndReturnsOk()
// Step 3. Arrange
// Last we arrange our test
$this->mock->shouldReceive('testymethod')->once();
// Step 2. Act
// Then we write how we the results will be asserted.
// The route should correspond with the controller executing the class method.
// Eg. TestyMethodController@test; return $this->class->testymethod()
**$this->call('GET', 'TestyController@test');**
// Step 1. Assert
// Start by writing the results we expect;
// If the controller issues no Exceptions we should get a response header status 200.
$this->assertResponseOk();
本质上 $mock->shouldReceive 是在模拟对象上设置一个侦听器,它正在等待方法运行 - 如果它运行则一切正常,否则你会得到一个 InvalidCountException。
希望对您有所帮助,祝您有美好的一天。
【讨论】:
【参考方案3】:我遇到过类似的问题:无法识别课程。尝试使用 __construct 方法对其进行初始化。这对我有用。 (在 setUp 方法中设置它不起作用)。
public function __construct()
$this->mock = Mockery::mock('TestyClass');
然后只调用测试方法:
$this->mock->shouldReceive('testymethod')->once();
【讨论】:
以上是关于在 Laravel 4 中使用 Mockery 模拟自定义类的主要内容,如果未能解决你的问题,请参考以下文章
使用 Mockery Eloquent 模型模拟 Laravel
Laravel 5 - 使用 Mockery 模拟 Eloquent 模型