【发布时间】:2018-02-21 23:35:02
【问题描述】:
晚安,我这里有点麻烦。我是第一次做 TDD,所以我不知道这种行为的根源。这篇文章看起来很长,但主要是因为我复制了相关代码的市长。
案例
顺便说一句,我使用 Laravel 作为后端来制作应用程序。
我正在测试具有admin 角色的User 可以创建“设施”对象,但其他用户不能。一些非常基本的东西。
问题
在测试端点时,它让角色user(常规角色)的用户创建对象。但是,当我尝试使用 Postman 对其进行测试时,它按应有的方式工作:阻止请求。
为了管理 acl,我正在使用 Laratrust 包(效果很好,已经测试过了)。
代码
routes/api.php // 这已经有了中间件:auth & api
Route::post('api/v1/facilities', 'FacilityController@store');
App\Htpp\Controllers\FacilityController.php
use App\Http\Requests\Facility\CreateFacilityRequest;
use App\Http\Resources\FacilityResource;
use App\Repositories\FacilityRepository;
use App\Services\ImageService;
use Illuminate\Http\Response;
// some code
/**
* Create a new Facility
*
* @param CreateFacilityRequest $request
* @return \Illuminate\Http\JsonResponse
*/
public function store(CreateFacilityRequest $request)
{
$data = $request->only(['name']);
$file = $request->file('image');
$data['image'] = ImageService::storeAs('images/facilities', $file, 'friendly', $data['name']);
$facility = $this->facilityRepository->create($data);
return response()->json([
"message" => "The facility has been added.",
"data" => new FacilityResource($facility)
], Response::HTTP_CREATED);
}
App\Http\Requests\Facility\CreateFacilityRequest.php
class CreateFacilityRequest extends FormRequest {
/**
* Determine if the user is authorized to make this request.
*
* @return bool
*/
public function authorize()
{
return auth()->user()->can('create-facilities');
}
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'name' => 'required|string|unique:facilities,name',
'image' => 'required|image'
];
}
}
最后,这是我的测试:
test\Feature\FacilityTest.php
/**
* @test
* Test for: a Facility can be registered only by an admin.
*/
public function a_facility_can_be_registered_only_by_an_admin()
{
/** Given a correct information for a facility */
\Storage::fake('public');
$data = ["name" => "Facility A", 'image' => UploadedFile::fake()->image('facility-a.jpg') ];
/** When the request is made by an admin */
$admin = $this->createUser([], 'admin');
$response = $this->apiAs($admin, 'POST','/api/v1/facilities', $data);
/** Then the facility should be registered */
$response->assertStatus(Response::HTTP_CREATED); // 201
/** When the request is made by somebody else */
$data = ["name" => "Facility B", 'image' =>UploadedFile::fake()->image('facility-b.jpg') ];
$regular_user = $this->createUser([], 'user');
$response = $this->apiAs($regular_user, 'POST','/api/v1/facilities', $data);
/** Then the request should be declined */
$this->assertTrue($regular_user->hasRole('user'));
$this->assertFalse($regular_user->can('create-facilities'));
$response->assertStatus(Response::HTTP_FORBIDDEN); // 403
\Storage::disk('facilities')->assertMissing('facility-b.jpg');
}
除此之外的所有断言都得到确认:
$response->assertStatus(Response::HTTP_FORBIDDEN); // 403
输出是这样的:
预期的状态代码为 403,但收到的是 201。
断言 false 为 true 失败。
时间:447 毫秒,内存:20.00MB
失败!测试:1,断言:4,失败:1。
进程以退出代码 1 结束
当我dd($response->json()) 它返回成功调用的常规 json。但在 Postman 中,它返回正确的:
{
"message" : "Unauthorized" // with status code 403
}
有人知道为什么吗?
更新
受保护的函数 apiAs()
protected function apiAs($user, $method, $uri, array $data = [], array $headers = []) : TestResponse
{
$headers = array_merge([
'Authorization' => 'Bearer '.\JWTAuth::fromUser($user),
'Accept' => 'application/json'
], $headers);
return $this->api($method, $uri, $data, $headers);
}
protected function api($method, $uri, array $data = [], array $headers = [])
{
return $this->json($method, $uri, $data, $headers);
}
【问题讨论】:
标签: php laravel testing laravel-5 laravel-5.5