当我想在单元测试中测试数组时,我遇到了一个小问题。
我想测试密钥的结构和类型,但我不知道如何处理它(我尝试过,我保证!)。
这是 json 输入:
{
"success": true,
"data": [
{
"id": 1,
"domains_id": 1,
"sub": "",
"type": "",
"ip_or_fqdn": "",
"created_at": "2022-05-14T08:30:18.000000Z",
"updated_at": "2022-05-14T08:30:18.000000Z"
}
],
"message": "Domain retrieved successfully."
}
目前有测试:
it('fetch zone entries [GET] with json response and check response type', function () {
TestCase::initDatabase();
Passport::actingAs(
User::factory()->make()
);
$response = $this->withHeaders([
'Accept' => 'application/json'
])
->json('GET', '/api/zone')
->assertStatus(200)
->assertJson(function (AssertableJson $json) {
$json->has('success')
->whereType('success', 'boolean')
->has('data')
->whereType('data', 'array')
->has('message')
->whereType('message', 'string');
});
TestCase::resetDatabase();
});
我想用这个过程测试“数据”数组键/值,当然,在这个闭包中;但这可能吗?
例如,您可以使用点符号
->assertJson(fn (AssertableJson $json) =>
$json->has('data.id')
->where('data.id', 1)
->missing('data.x')
);
最后,根据@ajthinking的提示,这是最终的测试,它有效,非常感谢!
it('fetch zone entries [GET] with json response and check response type', function () {
TestCase::initDatabase();
Passport::actingAs(
User::factory()->make()
);
$response = $this->withHeaders([
'Accept' => 'application/json'
])
->json('GET', '/api/zone')
->assertStatus(200)
->assertJson(function (AssertableJson $json) {
$json->has('success')
->whereType('success', 'boolean')
->has('data')
->whereType('data', 'array')
->has('data.0')
->has('data.0')
->has('data.0.id')
->has('data.0.sub')
->has('data.0.type')
->has('data.0.ip_or_fqdn')
->has('data.0.created_at')
->has('data.0.updated_at')
->whereType('data.0.id', 'integer')
->whereType('data.0.sub', 'string')
->whereType('data.0.type', 'string')
->whereType('data.0.ip_or_fqdn', 'string')
->whereType('data.0.created_at', 'string')
->whereType('data.0.updated_at', 'string')
->has('message')
->whereType('message', 'string');
});
TestCase::resetDatabase();
});
将来我将使用assertJsonStructure()来改进这个测试,以测试assertJson()闭包中的基本结构和测试类型。
编辑:
这是使用assertJsonStructure()方法进行的测试,效果很好:
it('fetch zone entries [GET] with json response and check response type', function () {
TestCase::initDatabase();
Passport::actingAs(
User::factory()->make()
);
$response = $this->withHeaders([
'Accept' => 'application/json'
])
->json('GET', '/api/zone')
->assertStatus(200)
->assertJsonStructure([
'success',
'data' => [
'*' => [
'id',
'sub',
'type',
'ip_or_fqdn',
'created_at',
'updated_at'
]
],
'message'
])
->assertJson(function (AssertableJson $json) {
$json->whereType('success', 'boolean')
->whereType('data', 'array')
->whereType('data.0.id', 'integer')
->whereType('data.0.sub', 'string')
->whereType('data.0.type', 'string')
->whereType('data.0.ip_or_fqdn', 'string')
->whereType('data.0.created_at', 'string')
->whereType('data.0.updated_at', 'string')
->whereType('message', 'string');
});
TestCase::resetDatabase();
});
您可以使用宏,例如用于结构测试
TestResponse::macro('assertJsonCollectionStructure',
fn (array $structure) =>
$this->assertJsonStructure([
'success,
'data' => [$structure],
'message',
])
);
然后使用它
->assertJsonCollectionStructure([
'id',
'domains_id',
// ...
])