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

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

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

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

Q&A

解決済

2回答

1944閲覧

railsのテストにrespond_toを使う理由

mitsuru793

総合スコア157

Ruby

Rubyはプログラミング言語のひとつで、オープンソース、オブジェクト指向のプログラミング開発に対応しています。

Ruby on Rails

Ruby on Railsは、オープンソースのWebアプリケーションフレームワークです。「同じことを繰り返さない」というRailsの基本理念のもと、他のフレームワークより少ないコードで簡単に開発できるよう設計されています。

0グッド

0クリップ

投稿2015/08/18 02:23

現在、Ruby on Rails チュートリアルのソースコードをgithubからダウンロードして、勉強のために閲覧しています。 Twitterのようにつぶやいたことを表示するアプリです。

下記はフォローとフォロワーの関係を表すRelationshipモデルのテストです。このモデルはUserモデル1対多の関係にあります。

ruby

1require 'spec_helper' 2 3describe Relationship do 4 5 let(:follower) { FactoryGirl.create(:user) } 6 let(:followed) { FactoryGirl.create(:user) } 7 let(:relationship) { follower.relationships.build(followed_id: followed.id) } 8 9 subject { relationship } 10 11 it { should be_valid } 12 13 describe "follower methods" do 14 it { should respond_to(:follower) } 15 it { should respond_to(:followed) } 16 its(:follower) { should eq follower } 17 its(:followed) { should eq followed } 18 end

このテストの中にrespond_toが2回使われてます。respond_toは対象オブジェクトに、シンボルで指定したプロパティが有るかどうか。言い換えると応答するかどうかを真理値で返すものだと理解しています。

今回の場合は、Relationshipモデルのインスタンス、relationship(subjectで指定したもの)にfollower, followedのプロパティが存在するかをチェックしているかと思います。わざわざこのチェックを行う理由、メリットは次の通りだと思うのですが他にありますでしょうか?

  1. メソッドテスト前に、そのメソッドが存在するかを確認する。
  2. テスト対象のプロパティが存在しない場合は、そのテストをskipするようにして時短を行う。
  3. テスターとコーダーが分業する際に、テスターが定義して欲しいプロパティを明示しておく。
  4. コードを書く前にテストに必要なプロパティを書くことで、設計図代わりに使うことができる。また、これがテストとして流用できる。

お手数おかけしますが、お答え頂ければ幸いです。
よろしくお願い致します。

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

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

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

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

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

guest

回答2

0

ベストアンサー

読み取られている内容で正しいです。
基本的に、テストファーストの考え方で、テスト実施中にエラーを発生させないためにrespond_toが挿入されているということかと。
テストを先に書くので、当然のようにuser.followerはNoMethodErrorを返しますが、これは想定された動作なので、テストでErrorではなくFailedを返してほしい訳です。
テスト中にErrorを返すのは、テストコードに問題がある場合で、想定された動作の時にはFailedを返す様にするのが正しいテストだ、というスタンスですね。

確か、一つのテスト中にFailedを返した時点で(Failedが発生したテストブロックの中の)残りをスキップされるので、its(:follower) { should eq follower }は実行されず、エラーも発生しないし、おっしゃるとおり時短されると思います。

投稿2015/08/18 04:22

rifuch

総合スコア1901

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

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

mitsuru793

2015/08/18 05:11

> テストでErrorではなくFailedを返してほしい訳です。 テストというのは特定のErrorを発生させて、それをFailedと扱っているのかと勘違いしておりました。よく考えてみたら、それだと期待値が複数になってしまいますね。だから真理値で判断しているのですね。 テストコードにエラーを発生させてしまったら、そのテストは異常ということもわかりました。今回の説明で、テストそのものをさらに知ることができ嬉しいです。 素晴らしいご説明、ありがとうございます。 毎回railsの質問に答えて頂き、大変助かっております。
guest

0

テストから読み取っている事は概ね正しいですが、このテストの目的の解釈がぼくとは異なります。「ぼくの解釈が正しい」と主張したいというわけではなくて「こんな考え方もあるよ」程度に聞いて頂ければ幸いです。

Rubyには静的な型付けされない言語です。リファクタリング等でプロパティ名が変えた時に変更が漏れている可能性があります。プロパティがあるかどうかのテストは、そういった問題に気づかせてくれるテストです。

Javaなどの静的型付け言語では、IDEがリファクタリングのサポートをしてくれますし、何よりコンパイラが名前があわない時はコンパイルエラーを出しておしえてくれます。それが静的型付言語の利点と言われています。

なお、

it { should respond_to(:follower) }

で失敗してもskipしてくれたりはしなかったと思います。

参考: Rubyにはウンザリ!動的型付け、副作用、およびオブジェクト指向プログラミング全般からの考察

投稿2015/08/18 02:53

編集2015/08/18 02:58
退会済みユーザー

退会済みユーザー

総合スコア0

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

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

mitsuru793

2015/08/18 05:23

> リファクタリング等でプロパティ名が変えた時に変更が漏れている可能性があります。 プロパティ名の変更にともない、前のプロパティ名を記述していた場所を変更するの忘れていたということでしょうか? > Javaなどの静的型付け言語では、IDEがリファクタリングのサポートをしてくれますし、何よりコンパイラが名前があわない時はコンパイルエラーを出しておしえてくれます。それが静的型付言語の利点と言われています。 Rubyは動的言語で変数にどんな型の値でも入れることができる。だから実行するまでその変数にどんな値が入るかわからないのですよね。けど、Javaだと型で変数に入る値を制限しているからコンパイル時にエラーを発生させることができるということでしょうか。 これだと、静的言語の場合はrespond_toのようなテストは必要なくなり、テストが楽になりますね。 個人の見解を聞かせていただくと、物事の見方が広がるので大変助かります。 ご回答頂き、ありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.50%

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

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

質問する

関連した質問