苦戦しているけれど、テストの書き方の基本が少しずつわかってきたので、まとめ。
そういえば、ブログを書いたり日報を書いたりするのがとても下手だと自分で思います。
読み返した時に自分が何に詰まっていたのか、それがどんな原因で、どう対応したら解決したかっていうのを意識してまとめて行きたいと思います。
戦いの記録
初回
- 詰まっていたこと: バリデーションしかかける自信がない
- 書いたテスト:modelのテスト(バリデーションだけ)
- もらった助言:「”自分で書いたメソッド"のテストを書こう」
2回目
- 詰まっていたこと:「自分で書いたメソッド」がどれかわからない。gemやrails自体の機能との区別がつかない。
- 書いたテスト:gemとか全く絡めてないメソッドのテスト
- もらった助言:「gemの機能を使って書き加えたテストも”自分で書いたメソッド”だよ」
3回目
3回目でこのテストならオッケー( ・∇・)いただきました。
初歩の初歩のテストコードでめちゃくちゃ苦戦して1週間使いました。辛かったです。
でも、オッケー頂いた時は、ただただ嬉しくで涙が・・・(● ˃̶͈̀ロ˂̶͈́)੭ꠥ⁾⁾
modelのメソッドのテストを書く(ユニットテスト)
基本的なことなので、このブログをいつか読み返している私は、ここに書くことなんてもう分かってて当然でしょって思ってて欲しい。
メソッドが何をしているのか
”自分で書いたメソッドに該当するのが悲しいことにomniauthを使ったメソッドで、正直usageとかomniauthを使いこなしている人たちのコードをみて写して書いたみたいなところがあったので、「果たしてこれはどうテストしたらいいんだろう」というのを考えるもの大変でした。
こんなメソッド。
def self.from_omniauth(auth, singend_in_recource = nil) where(provider: auth.provider, uid: auth.uid).first_or_create do |user| user.email = auth.info.email || User.create_unique_email user.password = Devise.friendly_token[0, 20] user.name = auth.info.name user.avatar_file_name = auth.info.image user end end
このメソッドでやりたいこと。
①where(provider: auth.provider, uid: auth.uid).first
の部分。
provider
がauth.provider
(このアプリではTwitterのみ)でuid
がauth.uid
の情報を持っている最初のユーザーを探す。
② or_create do |user|
は、該当するユーザーがいなかったらユーザーを新規登録する。
user.email = auth.info.email || User.create_unique_email user.password = Devise.friendly_token[0, 20] user.name = auth.info.name user.avatar_file_name = auth.info.image user
ユーザーの登録情報はemail
、password
、name
、avatar
で、provider(=Twitter)のアカウント情報を使うよ。
登録したユーザーを返して終わり。
というのがこのメソッドである。(テスト書かなかったらわからなかった)
やりたいことをテストする
①where(provider: auth.provider, uid: auth.uid).first
の部分。
provider
がauth.provider
(このアプリの場合はTwitterのみ)でuid
がauth.uid
の情報を持っている最初のユーザーを探す。
テストに書くこと。 *「過去にTwitter認証を使って登録している」という状態なので、テストではすでに登録したユーザーのデータを作成。
before do user = User.create( name: "TestUser", email: "testuser@example.com", provider: "twitter", password: "testpassword" ) end
- 「
provider
がauth.provider
(このアプリの場合はTwitterのみ)でuid
がauth.uid
の情報を持っている最初のユーザーを探す」をコードにする。
it "authenticate an user" do user = User.where(provider: "twitter").first expect(user.name).to eq ("TestUser") end
② or_create do |user|
は、該当するユーザーがいなかったらユーザーを新規登録する。
- 「ユーザーの登録情報は
email
、password
、name
、avatar
で、provider(=Twitter)のアカウント情報を使う」をコードにする。
it "create an user through Twitter's API" do user = User.create( name: "OtherUser", provider: "twitter", password: "otherpassword" ) expect(user.email).to be_empty end
Twitter認証の場合、アカウント情報にeメールアドレスがないっていう問題があるので、そこは別のメソッドとテストで書いています。
初めてテストっぽいテストを書いてみて
今回はfjord Boot Campの課題だったので、メソッドが先にあって、それを追う形でテストを書きました。 ですがテスト駆動型だとテストを先に書いて、やりたいことを明確にしてからメソッドにしていくんだなという感覚が少しは分かってきた気がします。
しかしまだこれはちょっとしたユニットテストに過ぎないし、もっと美しい書き方があるそうなので、もっともっと努力をしていきたいです。
テストを書くのは大変そうですが、テストを通してアプリ全体の設計やコードを美しくするというマインドも高めて行けたらなって思います。