jeudi 21 septembre 2017

Laravel: Using mock instance in Customised Route::model binding

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

Aucun commentaire:

Enregistrer un commentaire