Laravel:在自定义Route :: model绑定中使用模拟实例 [英] Laravel: Using mock instance in Customised Route::model binding
问题描述
Laravel中的路由模型绑定有助于将实例绑定到服务容器,以便在控制器操作中使用.而且美丽的是,当我想编写测试时,可以将模拟实例绑定到应用程序,从而替换绑定到容器的内容. -App::instance($className, $mockInstance);
Route model binding in Laravel, helps bind an instance to the service container, to be used in a controller action. And the beautiful thing is that when I want to write tests, I can bind a mock instance to the application, which replaces what is bound to the container. - App::instance($className, $mockInstance);
我已请求路线(Route::get("/{class_name}")
).我想根据路由参数class_name
的值返回类的实例.
I have made a request to the route (Route::get("/{class_name}")
). I want to return an instance of the class, depending on what the value of the route parameter class_name
is.
如果值是two
,则我想要Two
类的实例,对于One
类也是如此.请注意,这两个类都继承自AbstractClass
,因此返回的实例的类型为AbstractClass
(PHP7).
If the value is two
, I want an instance of the Two
class, likewise for the One
class. Notice that both classes inherit from AbstractClass
, so the returned instance is of type AbstractClass
, (PHP7).
问题:当我访问路线时,我得到了正确的实例.但是,当我要使用模拟实例时,它会覆盖模拟实例并创建/返回主实例.我需要使用模拟实例,以便可以对此设置期望.
Problem: When I make visit the route, I get the correct instance. But when I want to use the mock instance, it overrides the mock instance and creates/returns the main instance. I need to use the mock instance so I can set expectations on it.
我添加了一些代码,希望可以说明我的意思.
I've added some code, which I hope illustrates what I mean.
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进行开发
I am using PHP7.0, with Laravel5.4 for development
推荐答案
原因:
好吧,我想您会混淆Router bindings
与Container Bindings
.这两个在本质上是完全分开的.
Reason:
Well I guess you're confusing Router bindings
vs Container Bindings
. These two are completely separate in nature.
答案: 编写测试时,只需更新路由器绑定即可.
Answer: Just update the router bindings when you're writing tests.
$mock = Mockery::mock(AbstractClass::class);
$this->app->get('router')->bind('class', function () use ($mock) {
return $mock;
});
$response = $this->get("/test");
路由器绑定:
这些绑定仅在涉及路由时才能解决,而在使用app()
实例时则无法解决.
Router Bindings:
These bindings are only resolved when routing is involved, and it cannot be resolved when you're using app()
instance.
容器绑定: 容器绑定是单独的,根本不了解路由器绑定.
Container Bindings: Container bindings are separate and it doesn't know about the router bindings at all.
这篇关于Laravel:在自定义Route :: model绑定中使用模拟实例的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!