質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

Q&A

解決済

1回答

3279閲覧

Railsでコントローラのテスト(Rspec)を実行した時にテストが通らないと思っていたら、なぜか通っているのはなぜ!?

shyamahira

総合スコア19

RSpec

RSpecはRuby用のBDD(behaviour-driven development)フレームワークです。

Ruby on Rails 4

Ruby on Rails4はRubyによって書かれたオープンソースのウェブフレームワークです。 Ruby on Railsは「設定より規約」の原則に従っており、効率的に作業を行うために再開発を行う必要をなくしてくれます。

0グッド

1クリップ

投稿2015/12/14 04:16

everyday Rails RspecによるRailsテスト入門という参考書のコントローラのテストについて、下記のような例題がありました。


  • Pathリクエストをテストする

spec/controllers/contacts_controller_spec.rb

describe ContactsController do ~略~ describe 'PATCH #update' do before :each do @contact = create(:contact, firstname: 'Lawrence', lastname: 'Smith') end context "valid attributes" do example '要求された@contactを取得すること' do patch :update, id: @contact, contact: attributes_for(:contact) expect(assigns(:contact)).to eq(@contact) end ~略~

テストを実行すると、テストは通るのですが、なぜ上記のテストでテストがパスするのかがわかりませんでした。(assigns(:contact)の値と、@contactの値が一致していない気がします。)

ちなみにFactoryとControllerの内容は下記のとおりです。

spec/factories/contacts.rb

FactoryGirl.define do factory :contact do firstname { Faker::Name.first_name } lastname { Faker::Name.last_name } email { Faker::Internet.email } end end

app/controllers/contacts_controller.rb

class ContactsController < ApplicationController #before_action :authenticate, except: [:index, :show] before_action :set_contact, only: [:show, :edit, :update, :destroy] ~略~ # PATCH/PUT /contacts/1 # PATCH/PUT /contacts/1.json def update respond_to do |format| if @contact.update(contact_params) format.html { redirect_to @contact, notice: 'Contact was successfully updated.' } format.json { render :show, status: :ok, location: @contact } else format.html { render :edit } format.json { render json: @contact.errors, status: :unprocessable_entity } end end end ~略~

テスト内の各変数のプリントデバッグを試みると、下記のようになります。

spec/controllers/contacts_controller_spec.rb

describe ContactsController do ~略~ describe 'PATCH #update' do before :each do @contact = create(:contact, firstname: 'Lawrence', lastname: 'Smith') end context '有効な属性の場合' do example '要求された@contactを取得すること' do debug_attributes_for = attributes_for(:contact) patch :update, id: @contact, contact: debug_attributes_for expect(assigns(:contact)).to eq(@contact) ### puts("debug_attributes_forデバッグ") p debug_attributes_for puts("@contactデバッグ") p @contact puts("assigns(:contact)デバッグ") p assigns(:contact) ### end ~略~

テスト実行結果

~略~ PATCH#update 有効な属性の場合 debug_attributes_forデバッグ {:firstname=>"Ardith", :lastname=>"Effertz", :email=>"lesly.carter@mcdermott.org"} @contactデバッグ #<Contact id: 1, firstname: "Lawrence", lastname: "Smith", email: "westley@dickinson.org", created_at: "2015-12-14 04:06:43", updated_at: "2015-12-14 04:06:43"> assigns(:contact)デバッグ #<Contact id: 1, firstname: "Ardith", lastname: "Effertz", email: "lesly.carter@mcdermott.org", created_at: "2015-12-14 04:06:43", updated_at: "2015-12-14 04:06:43"> ~略~ Finished in 0.4773 seconds (files took 1.86 seconds to load) 20 examples, 0 failures, 4 pending

プリントデバッグした結果を見てもassigns(:contact)@contactが一致していませんが、テストは通っていて、なぜテストが通るのかが理解できないでいます。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

ActiveRecordのモデルの比較は idしか比較していないからです。

この例だとどちらのContactもidが1なので、等しいとみなされています。

https://github.com/rails/rails/blob/master/activerecord/lib/active_record/core.rb#L409-L414

投稿2015/12/14 09:46

hello-world

総合スコア1342

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

shyamahira

2015/12/21 13:15

お礼が遅くなり失礼しました。 おかげさまですっきりしました。 これからは疑問に感じたらソースを見るように心がけたいと思います。 ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問