let(:valid_attributes) {
skip("Add a hash of attributes valid for your model") }
これは create で使用しているデータです。有効なデータに変更しましょう。データの内 容は型に合わせて何でも設定してかまいません。ただし、時刻を設定するときはタイムゾー
let(:valid_attributes) {
{ title: 'aozora bunko', author: 'volunteer', published_on: Time.zone.now, showing: true } }
次はこちらです。
context "with valid params" do let(:new_attributes) {
{ title: 'Rails Guide', author: 'contributors',
published_on: Time.zone.now, showing: true } }
it "updates the requested book" do book = Book.create! valid_attributes
put :update, params: {id: book.to_param, book:
new_attributes}, session: valid_session book.reload
skip("Add assertions for updated state") end
(中略) end
ここは update をテストしています。まず変更するための有効なデータを設定します。
let(:new_attributes) { { title: 'Rails Guide' } }
そのあとの book.reload は、updateしたbookデータをデータベースから読み直し ています。次の行で変更した値を確認しましょう。
book.reload
expect(book.title).to eq new_attributes[:title]
3つ目のskipはこちらです。
let(:invalid_attributes) {
skip("Add a hash of attributes invalid for your model") }
これは、無効なデータのときにそれに対する何らかの処理がされているか、というテストの ためのものです。この1stリリースまででは特に無効なデータを想定していません。この
let(:invalid_attributes)
ブロックと、invalid_attributes
を呼んでいる 以下の場所を削除しておいてください。context "with invalid params" do
it "assigns a newly created but unsaved book as @book" do
post :create, params: {book: invalid_attributes}, session: valid_session expect(assigns(:book)).to be_a_new(Book)
end
it "re-renders the 'new' template" do
post :create, params: {book: invalid_attributes}, session: valid_session expect(response).to render_template("new")
end end
context "with invalid params" do it "assigns the book as @book" do
book = Book.create! valid_attributes
put :update, params: {id: book.to_param, book:
invalid_attributes}, session: valid_session expect(assigns(:book)).to eq(book)
end
it "re-renders the 'edit' template" do book = Book.create! valid_attributes
put :update, params: {id: book.to_param, book:
invalid_attributes}, session: valid_session expect(response).to render_template("edit") end
end
そしてテストを実行します。
username:~/workspace (master) $ rspec spec/controllers/books_controller_spec.rb F...
Failures:
1) BooksController GET #index assigns all books as @books Failure/Error: expect(assigns(:books)).to eq([book])
expected: [#<Book id: 7, title: "aozora bunko", author: "volunteer", published_on: "2016-12-16", showing: true, price: nil, created_at:
"2016-12-16 09:09:41", updated_at: "2016-12-16 09:09:41">]
got: #<ActiveRecord::Relation [#<Book id: 1, title: "徒然草", author: "吉田兼好", published_on: "1331-09-01", sho..., showing: true, price: nil,
created_at: "2016-12-16 09:09:41", updated_at: "2016-12-16 09:09:41">]>
(compared using ==) Diff:
@@ -1,2 +1,8 @@
-[#<Book id: 7, title: "aozora bunko", author: "volunteer",
published_on: "2016-12-16", showing: true, price: nil, created_at:
"2016-12-16 09:09:41", updated_at: "2016-12-16 09:09:41">]
+[#<Book id: 1, title: "徒然草", author: "吉田兼好", published_on: "1331-09-01", showing: nil, price: 3000, created_at: "2016-12-15 10:42:38", updated_at: "2016-12-15 10:42:38">,
+ #<Book id: 2, title: "吾輩は猫である", author: "夏目漱石",
published_on: "1905-08-01", showing: nil, price: 5000,
created_at: "2016-12-15 10:42:38", updated_at: "2016-12-15 10:42:38">, + #<Book id: 3, title: "怪人二十面相", author: "江戸川乱歩",
published_on: "1936-01-01", showing: nil, price: 3000,
created_at: "2016-12-15 10:42:38", updated_at: "2016-12-15 10:42:38">, + #<Book id: 4, title: "Rubyを作ってみた話", author: "Matz",
published_on: "1995-12-01", showing: nil, price: 2500,
created_at: "2016-12-15 10:42:38", updated_at: "2016-12-15 10:42:38">, + #<Book id: 5, title: "楽しいRailsの使い方", author: "DHH",
published_on: "2004-07-01", showing: nil, price: 8000,
created_at: "2016-12-15 10:42:38", updated_at: "2016-12-15 10:42:38">, + #<Book id: 6, title: "Rubyist Magazine", author: "日本Rubyの会",
published_on: "2004-09-01", showing: nil, price: 750,
created_at: "2016-12-15 10:42:38", updated_at: "2016-12-15 10:42:38">, + #<Book id: 7, title: "aozora bunko", author: "volunteer",
published_on: "2016-12-16", showing: true, price: nil,
created_at: "2016-12-16 09:09:41", updated_at: "2016-12-16 09:09:41">]
# ./spec/controllers/books_controller_spec.rb:39:
in block (3 levels) in <top (required)>' Finished in 0.12794 seconds (files took 1.9 seconds to load) 12 examples, 1 failure
rspec ./spec/controllers/books_controller_spec.rb:36 #
BooksController GET #index assigns all books as @books
failureの内容は以下のところです。
Failure/Error: expect(assigns(:books)).to eq([book])
期待値と結果が違うということですね。
期待値
expected: [#<Book id: 7, title: "aozora bunko",
author: "volunteer", published_on: "2016-12-16",
showing: true, price: nil, created_at: "2016-12-16 09:09:41", updated_at: "2016-12-16 09:09:41">]
結果
got: #<ActiveRecord::Relation [#<Book id: 1, title: "
徒然草", author: "吉田兼好", published_on: "1331-09-01", sho..., showing: true, price: nil,
created_at: "2016-12-16 09:09:41", updated_at: "2016-12-16 09:09:41">]>
そして、エラー箇所は'spec/controllers/books_controller_spec.rb' 39行目付近です。
# ./spec/controllers/books_controller_spec.
rb:39:in block (3 levels) in <top (required)>'
ここで何をしているかというと、bookというデータをcreateし、それを一覧ページ(index) で取得して、同じデータがassigns(:books)(@booksのこと)として取得されている か?というテストです。データが1つの場合はこれでいいですが、今回はseed.rbを使っ てテスト用データベースにデータを入れましたから、結果が合いません。ですので、ここで はassigns(:books)が取得したデータの数だけ確認しておきましょう。エラーになった
it "assigns all books as @books" do book = Book.create! valid_attributes
get :index, params: {}, session: valid_session expect(assigns(:books).count).to eq(7)
end
なお、テスト中にcreateしたデータは、テスト後には削除されます。このテストは何回実行 してもデータは7つのままです。便利ですね。
これで
'spec/controllers/books_controller_spec.rb'
のテストが全て通る ことを確認できたらOKです。エラーメッセージやコメントは、英語ですし赤い文字が並ぶとショックを受けますが、なぜエ ラーになったかが必ず書いていますので解決が早いですし、ダメなパターンの知識の蓄積 にもなりますので、がんばって読むようにしてください。
同 じ ように、
'spec/controllers/tags_controller_spec.rb'
の テスト も 実行して修正をしていきます。tags#show は削除しましたので、describe "GET#show" do ...
のテストは削除しましょう。修正後のサンプルは以下のとおりです。なる べく見ないで自力で解決してみてください。一度にすべて修正せずに、手間でも1つずつ確 認していくのがコツです。require 'rails_helper'
RSpec.describe TagsController, type: :controller do let(:valid_attributes) {
{ name: 'スポーツ' } }
let(:valid_session) { {} } describe "GET #index" do
it "assigns all tags as @tags" do tag = Tag.create! valid_attributes
get :index, params: {}, session: valid_session expect(assigns(:tags).count).to eq(6)
end end
describe "GET #new" do
it "assigns a new tag as @tag" do
get :new, params: {}, session: valid_session expect(assigns(:tag)).to be_a_new(Tag) end
end
describe "GET #edit" do
it "assigns the requested tag as @tag" do tag = Tag.create! valid_attributes
get :edit, params: {id: tag.to_param}, session: valid_session expect(assigns(:tag)).to eq(tag)
end end
describe "POST #create" do
context "with valid params" do it "creates a new Tag" do expect {
post :create, params: {tag: valid_attributes},
session: valid_session
}.to change(Tag, :count).by(1) end
it "assigns a newly created tag as @tag" do
post :create, params: {tag: valid_attributes},
session: valid_session
expect(assigns(:tag)).to be_a(Tag) expect(assigns(:tag)).to be_persisted end
it "redirects to the created tag" do
post :create, params: {tag: valid_attributes},
session: valid_session
expect(response).to redirect_to(Tag.last) end
end end
describe "PUT #update" do
context "with valid params" do let(:new_attributes) {
{ name: 'Sports' } }
tag = Tag.create! valid_attributes
put :update, params: {id: tag.to_param, tag: new_attributes},
session: valid_session
tag.reload
expect(tag.name).to eq new_attributes[:name]
end
it "assigns the requested tag as @tag" do tag = Tag.create! valid_attributes
put :update, params: {id: tag.to_param, tag: valid_attributes},
session: valid_session
expect(assigns(:tag)).to eq(tag) end
it "redirects to the tag" do
tag = Tag.create! valid_attributes
put :update, params: {id: tag.to_param, tag: valid_attributes},
session: valid_session
expect(response).to redirect_to(tag) end
end end
describe "DELETE #destroy" do
it "destroys the requested tag" do tag = Tag.create! valid_attributes expect {
delete :destroy, params: {id: tag.to_param}, session: valid_session }.to change(Tag, :count).by(-1)
end
it "redirects to the tags list" do tag = Tag.create! valid_attributes
delete :destroy, params: {id: tag.to_param}, session: valid_session expect(response).to redirect_to(tags_url)
end end end
最後は、
'spec/controllers/taggings_controller_spec.rb' です。まず、他
と同じようにskipデータを書き換えていきますが、TaggingはBookと Tagのidだけ
を持っているのでした。ですので、まずはBookとTagのデータを呼び出します。ここでは、テスト用データベースに入っているデータを使います。
let(:book) { Book.first } let(:tag) { Tag.first }
これで、bookと