¿Cómo burlarse de un servicio (o un ServiceProvider) cuando se ejecutan pruebas de funciones en Laravel?
Estoy escribiendo una pequeña API en Laravel, en parte para aprender este marco. Creo que he descubierto un agujero enorme en los documentos, pero puede deberse a que no entiendo la "forma Laravel" de hacer lo que quiero.
Estoy escribiendo una API HTTP para, entre otras cosas, enumerar, crear y eliminar usuarios del sistema en un servidor Linux. La estructura es así:
Rutas a/v1/users
conectarGET
, POST
yDELETE
verbos a métodos de controladorget
, create
ydelete
respectivamente.El controladorApp\Http\Controllers\UserController
en realidad no ejecuta llamadas al sistema, eso lo hace un servicioApp\Services\Users
. El servicio es creado por un proveedor de serviciosApp\Providers\Server\Users
que registra unasingleton
del servicio en diferido.Laravel crea instancias del servicio automáticamente y se inyecta automáticamente en el constructor del controlador.OK, todo esto funciona. También he escrito un código de prueba, así:
public function testGetUsers()
{
$response = $this->json('GET', '/v1/users');
/* @var $response \Illuminate\Http\JsonResponse */
$response
->assertStatus(200)
->assertJson(['ok' => true, ]);
}
Esto también funciona bien. Sin embargo, esto utiliza los enlaces normales paraUserService
, y quiero poner un ficticio / simulacro aquí en su lugar.
Creo que necesito cambiar miUserService
a una interfaz, lo cual es fácil, pero no estoy seguro de cómo decirle al sistema de prueba subyacente que quiero que ejecute mi controlador, pero con un servicio no estándar. VeoApp::bind()
surgiendo en Stack Overflow responde cuando se investiga esto, peroApp
no está automáticamente en el alcance de las pruebas generadas por artesanos, por lo que se siente como agarrarse a las pajillas.
¿Cómo puedo crear una instancia de un servicio ficticio y luego enviarlo a Laravel durante la prueba, para que no utilice el ServiceProvider estándar?