我如何使用 Laravel 5.1、Phpunit 和 Mockery 测试在同一个 class 上调用静态方法的 eloquent 模型方法?

How can I test an eloquent model method which calls a static method on the same class using Laravel 5.1, Phpunit and Mockery?

我有一个 class,我正在尝试测试其中一个方法,但其中一个方法调用了同一个 class 上的静态方法。我想知道如何在没有静态方法的情况下测试第一个方法并存根以便我只测试第一个方法?

举个傻class的例子。

class MyEloquentModel extends Model
{
    // Returns input concatenated with output of bar for that input
    public function foo($input) {
        $bar = MyEloquentModel::bar($input);
        return $input." ".$bar;
    }

    // Returns world if input received is hello
    public static function bar($input) {
        if ($input == "hello") {
            return "world"; 
        }
    }
}

这是我试过的测试:

class MyEloquentModelTest extends TestCase 
{ 
    public function test_foo_method_returns_correct_value() 
    { 
        // Mock class 
        $mock = \Mockery::mock('App\MyEloquentModel');
        $mock->shouldReceive('hello') 
            ->once() 
            ->with() 
            ->andReturn('world');

        // Create object
        $my_eloquent_model = new MyEloquentModel;

    $this->assertTrue($my_eloquent_model->foo('hello') == "hello world");
    }
}

就目前而言,测试returns"Could not load mock App\MyEloquentModel, class already exists"

你可以这样做:

class MyEloquentModelTest extends TestCase 
{ 
    public function test_foo_method_returns_correct_value() 
    { 
        // Mock class 
        $my_mocked_eloquent_model = Mockery::mock('App\MyEloquentModel[bar]');
        $my_mocked_eloquent_model->shouldReceive('bar') 
            ->once() 
            ->with('hello') 
            ->andReturn('world');

    $this->assertEquals("hello world", $my_mocked_eloquent_model->foo('hello'));
    }
}

这是为 MyEloquentModel class 创建的部分模拟,其中只有方法 "bar" 被模拟。在 shouldReceive 方法中,应该指定要模拟的方法,而不是方法的参数(如您指定的那样)。相反,对于 with 方法,您应该指定您希望将哪些参数提供给该方法。

您得到 "Could not load mock App\MyEloquentModel, class already exists" 的错误很可能是因为您首先为 MyEloquentModel class 指定了一个模拟,然后尝试使用 [=13 创建 class 的新实例=].正如您在我的回复中看到的那样,您不应该创建 class 的新实例,而是创建一个模拟,您将使用它来调用要测试的方法。