问题
I am trying to test a Laravel REST API, through phpunit. While testing REST calls, I am unable to isolate REST calls test.
In Laravel, I understand a few options like using traits DatabaseMigrations
, DatabaseRefresh
, DatabaseTransactions
. But I can't use these for the following reasons:
DatabaseMigrations
: The app does not have proper migrations. Even if it had, those would be quite in-efficient.DatabaseRefresh
: Same as above.DatabaseTransactions
. The problem I see is that call to HTTP API is a completely different process. These are not within the same transaction. So a test that inserts data to setup the test case is not seen by HTTP call. Also, if data is inserted by HTTP calls like will be visible to other tests.
I can't write unit tests without calling HTTP; the app is not written in such a way. Entire code is in Routes
or in Controller
is not otherwise testable.
回答1:
i test my my endpoints with the json function ( i believe there is a POST and GET method as well, but i need to pass in data and headers)
public function test_endpoint() {
$result = $this->json('POST', '/api', ['key' => 'data'], ['Header' => "Value"]);
}
i have unit and feature tests as well, but i use this for testing graphQL endpoint.
回答2:
So in my example void
means that our method does not returning anything.
postJson
means we expect JSON
response, either we can do just $this->post()
You can make calls like this
public function test_create_order() : void
{
$response = $this->postJson('/make-order',[
'foo' => 'bar',
'baz' => 'bat'
]);
// To make sure it is returning 201 created status code, or other code e.g. (200 OK)
$response->assertStatus(201);
// To make sure it is in your desired structure
$response->assertJsonStructure([
'id',
'foo',
'baz',
]);
// Check if response contains exactly that value, what we inserted
$this->assertEquals('bar', $response->json('data.foo'));
// Check that in the database created that record,
// param 1 is table name, param 2 is criteria to find that record
// e.g. ['id' => 1]
$this->assertDatabaseHas('orders', [
'foo' => 'bar'
]);
// Also there is other method assertDatabaseMissing, that works like above
// just in reverse logic, it is checking that there is no record with that criteria
}
来源:https://stackoverflow.com/questions/65469680/laravel-rest-api-testing-in-phpunit