ここで一度にたくさんの新しいこと(Laravel、PHPUnitなど)を学ぼうとすると、これはおそらく疲れた脳の問題ですが、それでも助けていただければ幸いです。
LaravelをAPIレイヤーとして、AngularJSをフロントエンドとして使用する非常に基本的な「ブログ」プロジェクトがあります。APIエンドポイントを単体テストしたいのですが、その方法がわかりません。テスト関数でJSONを処理します。
TestGetBlogPosts()を実行しようとすると、CLIでJSON出力のように見えますが、json_decode()を実行できず、オブジェクトの特定の部分が期待した結果と一致することを確認できません。ここでは、結果配列の最初のオブジェクトのIDがID「1」であることを確認したいだけです。
テストから受け取った結果は次のとおりです。1)ExampleTest :: testGetBlogPosts ErrorException:非オブジェクトのプロパティを取得しようとしています
どんな助けや提案も大歓迎です!
TL; DR:テストケースがAPIエンドポイントからのJSON応答を正しく処理していません
コントローラー
class HomeController extends BaseController {
/*
|--------------------------------------------------------------------------
| Default Home Controller
|--------------------------------------------------------------------------
|
| You may wish to use controllers instead of, or in addition to, Closure
| based routes. That's great! Here is an example controller method to
| get you started. To route to this controller, just add the route:
|
| Route::get('/', 'HomeController@showWelcome');
|
*/
public function showWelcome()
{
return View::make('hello');
}
public function getBlogPosts()
{
$posts = Post::get()->take(5)->toJson();
// echo $posts; PER THE ACCEPTED ANSWER, RETURN NOT ECHO
return $posts;
}
public function getSinglePost($postId)
{
$posts = Post::find($postId)->toJson();
// echo $posts; PER THE ACCEPTED ANSWER, RETURN NOT ECHO
return $posts;
}
}
テストファイル
class ExampleTest extends TestCase {
/**
* A basic functional test example.
*
* @return void
*/
public function testBasicExample()
{
$crawler = $this->client->request('GET', '/');
$this->assertTrue($this->client->getResponse()->isOk());
}
public function testGetBlogPosts()
{
$response = $this->call('GET', 'api/getBlogPosts');
$array = json_decode($response);
$result = false;
if($array[0]->id == 1)
{
$result = true;
}
$this->assertEquals(true, $result);
}
}
要求に応じて、完全なテスト出力
root @ Homestead:/ home/vagrant/Laravel/Homestead/Blog#phpunit PHPUnit 3.7.28 by SebastianBergmann。
/home/vagrant/Laravel/Homestead/Blog/phpunit.xmlから読み取った構成
.E [{"id": "1"、 "user_id": "1"、 "title": "これはテスト投稿です"、 "post_body": "testststs"、 "created_at": "2014-08-07 19:26:26 "、" updated_at ":" 2014-08-07 19:26:26 "}、{" id ":" 2 "、" user_id ":" 75 "、" title ":" Libero rerum rem praesentium et et at doloribusasperiores。 "、" post_body ":" Commodi aut beatae aut veritatis eumsolutasint。Inautcumque iurequis。 "、" created_at ":" 2014-08-07 19:26:26 "、" updated_at ":" 2014-08-07 19:26:26 "}]
時間:1.85秒、メモリ:18.50Mb
1つのエラーがありました:
1)ExampleTest :: testGetBlogPosts ErrorException:非オブジェクトのプロパティを取得しようとしています
/home/vagrant/Laravel/Homestead/Blog/app/tests/ExampleTest.php:22
失敗!テスト:2、アサーション:1、エラー:1。
ブラウザでこのエンドポイントに移動すると、これが表示されます
[
{
id: 1,
user_id: 1,
title: "This is a test post",
subtitle: "",
post_body: "testststs",
created_at: "2014-08-07 19:26:04",
updated_at: "2014-08-07 19:26:04"
},
{
id: 2,
user_id: 18,
title: "Rem deserunt dolor odit tempore qui eaque labore.",
subtitle: "",
post_body: "Ea a adipisci molestiae vel dignissimos. Ea blanditiis et est.",
created_at: "2014-08-07 19:26:04",
updated_at: "2014-08-07 19:26:04"
}
]
コントローラのgetBlogPosts()
メソッドは、それを返すのではなく、$post
をエコーします。これは、テストの$response
にはjson_decode
への何も含まれないことを意味します。
あなたが今までにそれを理解したことを願っていますが、これが私が使用するものです:
$array = json_decode($response->getContent());
/tests/TestCase.php
にメソッドを追加すると、非常に役立ちます。
/**
* dumps json result
* @param string $function can be print_r, var_dump or var_export
* @param boolean $json_decode
*/
public function dump($function = 'var_export', $json_decode = true) {
$content = $this->response->getContent();
if ($json_decode) {
$content = json_decode($content, true);
}
// ❤ ✓ ☀ ★ ☆ ☂ ♞ ☯ ☭ € ☎ ∞ ❄ ♫ ₽ ☼
$seperator = '❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤ ❤';
echo PHP_EOL . $seperator . PHP_EOL;
$function($content);
echo $seperator . PHP_EOL;
return $this;
}
次に、json呼び出し後の任意の時点で呼び出すことができます。
public function testInvalidPostID() {
$this->json('PUT', '/posts/2222/sh-comments/1001', [
'input' => 'SomeThing'
], [
'Authorization' => 'Bearer ' . app('jwt')->getTokenForUser(2)
])->dump() //dumpnig output as array
->seeJsonStructure(['errors' => [
'*' => [
'message'
]
]
])->assertResponseStatus(404);
}
応答オブジェクトから直接json
メソッドを呼び出すことができます。
$response = $this->getJson('/foo');
$json = $response->json(); // ['foo' => 'bar', 'baz' => 'boo']
また、引数としてキーを受け入れます。
$foo = $response->json('foo'); // 'bar'