【问题标题】:Mocking a custom class with Mockery in Laravel 4在 Laravel 4 中使用 Mockery 模拟自定义类
【发布时间】: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;
    }   
}

【问题讨论】:

    标签: php unit-testing laravel phpunit mockery


    【解决方案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();
      

      【讨论】:

        猜你喜欢
        • 2014-01-09
        • 2016-01-14
        • 2014-11-05
        • 2016-08-17
        • 2015-03-27
        • 2022-01-04
        • 1970-01-01
        • 2019-10-24
        • 2017-04-25
        相关资源
        最近更新 更多