I am writing test for some controller method that will validate request data and create document by 3rd party API. Then it should return response with 201
status code. I am using mocking to mock my service class that is creating document. Here is my controller:
public function margin(MarginRequest $request){
$data = $request->validated();
$fileId = $this->documentService->createDocument(auth()->user()->id, SignableDocumentAbstract::MARGIN_CERTIFICATE, new MarginDocument(), $data);
return response()->json([
'code' => 201,
'message' => 'Margin agreement generated successfully',
'data' => [
'uuid' => $fileId
]
], 201);
}
And my test:
public function test_public_margin()
{
$marginData = (new MarginFaker())->fake();
Auth::shouldReceive('user')->once()->andReturn((object)['id' => 999999]);
$this->mock(DocumentService::class, function (MockInterface $mock) {
$mock->shouldReceive('createDocument')
->once()
->andReturn(Str::random());
});
$request = MarginRequest::create('/api/public/documents/margin', 'POST', $marginData);
$response = app(PublicController::class)->margin($request);
$this->assertEquals(201, $response->getStatusCode());
}
Everything look OK but when I run my test it throws error that
Call to a member function validated() on null
It is given in $data = $request->validated();
line of controller. But I can't understand why my $request
is recognized as null. Even if I dump request object by dump($request)
I can see that it is object and holds all required fields inside.
Then what can be the reason, why I can't call validated()
method while testing?
CodePudding user response:
You do not test like that when you want to test a URL. You NEVER mock a controller or do new Controller
and call a method inside it.
You have to read the HTTP Test section of the documentation.
So, your test should look like this:
public function test_public_margin()
{
$this->actingAs(User::factory()->create());
$this->mock(DocumentService::class, function (MockInterface $mock) {
$mock->shouldReceive('createDocument')
->once()
->andReturn(Str::uuid());
});
$response = $this->post(
'/api/public/documents/margin',
['pass the needed data as an array, so the validation passes']
);
$response->assertStatus(201);
}