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);
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.
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.
}
I am using PHP7.0, with Laravel5.4 for development