2016-11-04 3 views
0

Я работаю над добавлением JWT authentication в свой Lumen API. Пожалуйста, учтите, что я новичок в Lumen, дизайне API и TDD. Перед добавлением аутентификации все тесты проходили. Честно говоря, все, кажется, работает отлично, только когда я запускаю phpunit. Трудно понять, когда я запускаю тот же тест в почтальоне. У меня нет проблем, однако, когда я дам ответ в phpunit, я получаю NULL. Может быть, свежий набор глаз может помочь мне?Недействительный JSON был возвращен с маршрута. Возможно, было исключено исключение?

Я добавил jwt.auth связующее ПО моим ограниченным маршрутам:

routes.php

// all other code omitted 

$app->group([ 
    'prefix'  => $version . '/authors', 
    'middleware' => 'jwt.auth', 
    'namespace' => 'App\Http\Controllers', 
], function ($app) { 

    $app->get('/{id:[\d]+}', ['as' => 'authors.show', 'uses' => '[email protected]']); 

}); 

Часть моего контроллера заключается в следующем:

AuthorsController.php

class AuthorsController extends Controller 
{ 

    // all other code omitted 

    public function show($id) 
    { 
    return $this->item(Author::findOrFail($id), new AuthorTransformer()); 
    } 

} 

Моя модель выглядит следующим образом

Author.php

class Author extends Model 
{ 
/** 
* The attributes that are mass assignable 
* 
* @var array 
*/ 
    protected $fillable = ['name', 'biography', 'gender']; 

    public function books() 
    { 
    return $this->hasMany(Book::class); 
    } 
} 

И мой Transformer выглядит следующим образом:

AuthorTransformer.php

class AuthorTransformer extends TransformerAbstract 
{ 

    protected $availableIncludes = [ 
    'books', 
    ]; 

    public function includeBooks(Author $author) 
    { 
    return $this->collection($author->books, new BookTransformer()); 
    } 

    /** 
    * Transform an author model 
    * 
    * @param Author $author 
    * @return array 
    */ 
    public function transform(Author $author) 
    { 
    return [ 
     'id'  => $author->id, 
     'name'  => $author->name, 
     'gender' => $author->gender, 
     'biography' => $author->biography, 
     'created' => $author->created_at->toIso8601String(), 
     'updated' => $author->created_at->toIso8601String(), 
    ]; 
    } 
} 

И мои тесты следующим образом:

TestCase.php

class TestCase extends Laravel\Lumen\Testing\TestCase 
{ 

// all other code omitted 

/** 
* Convenience method for creating a user 
* 
* @return $user 
*/ 
    protected function userFactory() 
    { 

    $user = factory(\App\User::class, 1)->create(['password' => app('hash')->make('supersecret')]); 

    return $user; 
    } 

/** 
* Convenience method for getting jwt and authenticating 
* 
* @return $body 
*/ 
    protected function jwtAuthTest($method, $url, $body = []) 
    { 
    $user = $this->userFactory(); 

    $token = JWTAuth::fromUser($user); 
    JWTAuth::setToken($token); 
    $headers = array(
     "Accept"  => "application/json", 
     "Authorization" => "Bearer " . $token, 
    ); 

    switch ($method) { 
     case 'get': 
     $this->get($url, $body, $headers); 
     break; 
     case 'post': 
     $this->post($url, $body, $headers); 
     break; 
     case 'put': 
     $this->put($url, $body, $headers); 
     break; 
     case 'patch': 
     $this->patch($url, $body, $headers); 
     break; 
     case 'delete': 
     $this->delete($url, $body, $headers); 
     break; 
    } 

    $data = json_decode($this->response->getContent(), true); 

    return $data; 
    } 

} 

AuthorsControllerTest.php

class AuthorsControllerTest extends TestCase 
{ 

    // all other code omitted 

/** @test **/ 
    public function show_should_fail_on_an_invalid_author() 
    { 
    $body = $this->jwtAuthTest('get', '/v1/authors/1234'); 

    // this works fine... 
    $this->seeStatusCode(Response::HTTP_NOT_FOUND); 

    // NULL?? 
    var_dump($body); 
    } 
} 

Мой ответ должен быть:

{ 
    "error": { 
    "message": "Not Found", 
    "status": 404 
    } 
} 

Однако я получаю NULL

Когда я тестирую один и тот же маршрут с действительным маркером в Почтальон я получаю, что то, что я ожидал в моих тестах:

{ 
    "error": { 
    "message": "Not Found", 
    "status": 404 
    } 
} 

Внезапно мой маршрут возвращается нуль в PHPUnit испытаний. Я не могу понять, почему?

Мой обработчик выглядит следующим образом:

// all other code omitted 
class Handler extends ExceptionHandler 
{ 
    /** 
    * A list of the exception types that should not be reported. 
    * 
    * @var array 
    */ 
    protected $dontReport = [ 
    AuthorizationException::class, 
    HttpException::class, 
    ModelNotFoundException::class, 
    ValidationException::class, 
    ]; 

    /** 
    * Report or log an exception. 
    * 
    * This is a great spot to send exceptions to Sentry, Bugsnag, etc. 
    * 
    * @param \Exception $e 
    * @return void 
    */ 
    public function report(Exception $e) 
    { 
    parent::report($e); 
    } 

    /** 
    * Render an exception into an HTTP response. 
    * 
    * @param \Illuminate\Http\Request $request 
    * @param \Exception $e 
    * @return \Illuminate\Http\Response 
    */ 
    public function render($request, Exception $e) 
    { 
    if ($request->wantsJson()) { 
     $response = [ 
     'message' => (string) $e->getMessage(), 
     'status' => 400, 
     ]; 

     if ($e instanceof HttpException) { 
     $response['message'] = Response::$statusTexts[$e->getStatusCode()]; 
     $response['status'] = $e->getStatusCode(); 
     } else if ($e instanceof ModelNotFoundException) { 
     $response['message'] = Response::$statusTexts[Response::HTTP_NOT_FOUND]; 
     $response['status'] = Response::HTTP_NOT_FOUND; 
     } 

     if ($this->isDebugMode()) { 
     $response['debug'] = [ 
      'exception' => get_class($e), 
      'trace'  => $e->getTrace(), 
     ]; 
     } 

     return response()->json(['error' => $response], $response['status']); 
    } 

    return parent::render($request, $e); 

    } 

} 

Когда мой тест не я получаю:

There was 1 failure: 

1) Tests\App\Http\Controllers\AuthorsControllerTest::show_should_fail_on_an_invalid_author 
Invalid JSON was returned from the route. Perhaps an exception was thrown? 

Пожалуйста, дайте мне знать, если вам нужно что-нибудь еще и спасибо заранее.

Исходный код: https://github.com/studio174/gscp

ответ

0

Проблема заключается в TestCase.php был простой коллизия имен и неправильное использование метода GET():

TestCase.php

/** 
* Convenience method for getting jwt and authenticating 
* 
* @return $body 
*/ 
    protected function jwtAuthTest($method, $url, $body = []) 
    { 
    $user = $this->userFactory(); 

    $token = JWTAuth::fromUser($user); 
    JWTAuth::setToken($token); 
    $headers = array(
     "Accept"  => "application/json", 
     "Authorization" => "Bearer " . $token, 
    ); 

    switch ($method) { 
     case 'get': 
     // [FIX] removed $body from get request as this was overwriting my headers 
     // and causing my handler to return plain text instead of JSON 
     $this->get($url, $headers); 
     break; 
     case 'post': 
     $this->post($url, $body, $headers); 
     break; 
     case 'put': 
     $this->put($url, $body, $headers); 
     break; 
     case 'patch': 
     $this->patch($url, $body, $headers); 
     break; 
     case 'delete': 
     $this->delete($url, $body, $headers); 
     break; 
    } 

    // [FIX] changed $body= json_decode($this->response->getContent(), true); 
    $data = json_decode($this->response->getContent(), true); 

    return $data; 
    } 
Смежные вопросы