Laravel:在Customized Route ::模型绑定中使用模拟实例

时间:2017-09-21 23:02:11

标签: php laravel testing mocking mockery

Laravel中的路由模型绑定,有助于将实例绑定到服务容器,以用于控制器操作。而美妙的是,当我想编写测试时,我可以将一个模拟实例绑定到应用程序,该实例将替换绑定到容器的内容。 - App::instance($className, $mockInstance);

我已向路线(Route::get("/{class_name}"))发出请求。我想返回类的实例,具体取决于路由参数class_name的值。

如果值为two,我想要Two类的实例,同样适用于One类。请注意,这两个类都继承自AbstractClass,因此返回的实例的类型为AbstractClass,(PHP7)。

问题:当我访问路线时,我得到了正确的实例。但是当我想使用mock实例时,它会覆盖mock实例并创建/返回主实例。我需要使用模拟实例,所以我可以设置它的期望。

我添加了一些代码,我希望说明我的意思。

abstract class AbstractClass {
// abstract parent class
}

class One extends AbstractClass {
// single child class
}

class Two extends AbstractClass {
// another single child class
}

// I put this inside the `bind` method of the RouteServiceProvider
Route::bind("class_name", function (string $class_name) : AbstractClass {
 // I wish to return an instance to the route, based on the string that was passed - "one" or "two"
 $class = ucfirst($class_name);
 return new $class();
});

// test
public function testSomething () {
 $mockInstance = Mockery::mock(AbstractClass::class);
 App::instance(AbstractClass::class, $mockInstance);
 $response = $this->get("/one");
}
// controller method
public function action (AbstractClass $instance) {
 // I want to see/use the mock instance here, for testing
 // and the main instance otherwise.
}

我正在使用PHP7.0,使用Laravel5.4进行开发

1 个答案:

答案 0 :(得分:1)

<强>原因: 好吧,我想你会混淆Container Bindings vs $mock = Mockery::mock(AbstractClass::class); $this->app->get('router')->bind('class', function () use ($mock) { return $mock; }); $response = $this->get("/test"); 。这两者本质上是完全分开的。

<强>答案: 只需在编写测试时更新路由器绑定。

app()

路由器绑定: 这些绑定仅在涉及路由时解析,并且在您使用Some[Foo]实例时无法解析。

容器绑定: 容器绑定是分开的,根本不知道路由器绑定。