前回からの続き
前回は、Threadのテストデータを作成する際に、固定のデータしかつくれないよ、というところで終わってました。
www.tohuandkonsome.site
UserFactory.phpを修正する
前回のUserFactory.php
<?php
$factory->define(App\Thread::class, function (Faker $faker) {
return [
'user_id' => 1,
'title' => "ピンキーのかわいさについて",
'body' => "動いているところがいいよね"
];
});
まず、Threadに持たせるuser_idは、Userデータが存在するuser_idを設定するようにします。
これだけ聞くと、自分だったら以下のようにuser_idの部分にデータベースからUserの情報をとってくることをしてたかもしれません。
\App\User::find(1)->id
ってなんぞって思われ方は無視しても特に問題はないです!
言いたかったことは、存在するUserのidをThreadのuser_idに設定したいのであれば、存在するUserの情報をデータベースからとってきれ、それを設定する、ということをするという方法をとってただろうなぁということです。
UserFactory.php
<?php
$factory->define(App\Thread::class, function (Faker $faker) {
return [
'user_id' => \App\User::find(1)->id,
'title' => "ピンキーのかわいさについて",
'body' => "動いているところがいいよね"
];
});
一方、頼りにしているLaracastでは、こうしていました。
UserFactory.php(抜粋)
<?php
$factory->define(App\Thread::class, function (Faker $faker) {
return [
'user_id' => factory('App\User')->create()->id,
'title' => "ピンキーのかわいさについて",
'body' => "動いているところがいいよね"
];
});
存在しているUserのuser_idをセットするという発想ではなく、Threadのテストデータ作成の際に、Userをつくっちゃって、そのidを設定すればいいじゃないという発想ですね。
すごい!
(ただ、1対多のリレーションのデータを作成したいときにはどうするんだろう、とふと思いました)
さて、これで作成されるThreadのテストデータには、必ず対応するUserがいることになります。
せっかくなのでtitle
とbody
もランダムな文字列が設定されるようにしちゃいましょう(残念ですが)。
UserFactory.php(抜粋)
<?php
$factory->define(App\Thread::class, function (Faker $faker) {
return [
'user_id' => factory('App\User')->create()->id,
'title' => $faker->sentence,
'body' => $faker->paragraph
];
});
Faker
というクラスのメソッドでいい感じにデータを作成することができるみたいです。
こちらのFakerなんですが、githubにどんなメソッドがあって、どんなデータが作成されるかが書いてあります。
github.com
日本語用のFakerもあったりするみたいなのですが、こちらは試せてません。
話を戻してテストコード
回を跨いでしまったので、何をやってたか忘れかけてましたが、テストコードです。
前回はこんな感じで終わってましたね。
ThreadTest.php
<?php
@return
public function test_all_user_can_view_thread()
{
$thread = ???
$response = $this->get('/thread');
$response->assertSee($thread->body);
}
このThreadTest.php
を以下のように修正します。
ThreadTest.php
<?php
@return
public function test_all_user_can_view_thread()
{
$thread = factory('App\Thread')->create();
$response = $this->get('/thread');
$response->assertSee($thread->body);
}
くどいようですが、assertSee
で$thread->bodyの文字列がレスポンスの中にあるかを確認しています。
さて、このテストコードをクリアするために、実装を書いていきましょう。
実装を書く
ここでは、/thread
にアクセスしにきたときの制御を書くThreadController.php
と画面に描画されるHTMLの素となるindex.blade.php
を書いていきます。
コントローラーの修正
コントローラーはこんな感じになります。
ThreadController.php
<?php
namespace App\Http\Controllers;
use App\Thread;
use Illuminate\Http\Request;
class ThreadController extends Controller
{
public function index(Thread $thread)
{
$threads = $thread->all();
return view('thread.index', compact('threads'));
}
}
Thread
クラスはメソッドの中でnewして、インスタンス化してももちろんいいはず。
ただ、Laravelは引数にクラスを書いてあげると、それをインスタンス化して渡してくれるという機能を備えているので、ここでは引数に指定しているよ。
この引数に指定してインスタンス化くれることを「依存性の注入」みたいな表現で書かれていたりする。(間違ってたらごめんよ!)
依存性の注入を紐解けば、DIコンテナみたいな話がでてくるんだけど、このへんんお有用性があんまりわかってないので、しっくりきたらまた書こうと思うんだ。
(どうもクラス間の依存性をなくすことでテストしやすいコードが〜みたいな話なので、今回の学習を通して理解できれば幸せ)
index.blade.phpの修正
/resources/views
配下にthread
ディレクトリを作成して、index.blade.php
を作成するよ。
index.blade.php
<h1>This is Thread!</h1>
<ul>
@foreach($threads as $thread)
<li>{{ $thread->title }}</li>
<li>{{ $thread->body }}</li>
<hr/>
@endforeach
</ul>
ここでは最小限のコードにするよ。
テストコードの実行
さあ、これでテストコードを実行してみよう。
テストコードの実行
$ phpunit
PHPUnit 6.4.4 by Sebastian Bergmann and contributors.
..... 5 / 5 (100%)
Time: 1.47 seconds, Memory: 14.00MB
OK (5 tests, 5 assertions)
無事、通りましたね!
試しにブラウザで/thread
にアクセスしてみると 、こんな画面が表示されました。
せっかくなので、テストコードについても、thread->body
だけではなく、`thread->title'も追加しておきました。
<?php
@return
public function test_all_user_can_view_thread()
{
$thread = factory('App\Thread')->create();
$response = $this->get('/thread');
$response->assertSee($thread->body)
->assertSee($thread->title);
}
ここまでのソース
github.com