RSpec 一ヶ月さわさわしたので まとめてみた @yuuto
今日やること Rspec 周りの基本的なところをざーっと。 独学なので間違ってても知りません。 環境構築とかは書いてません。 WEB+DB Press vol.61 あたりが詳しいかも。
環境 Ruby 1.8.7,Rails 3.0.7,Rspec 2.4.0 ↓ GemFile のテスト部分
RSpec とは プログラムの振る舞いを記述するための DSL TDD ではなく振る舞い駆動開発( Behaviour Driven Development: BDD) のための言語
DSL って? ドメイン特化言語( DomainSpecificLanguage: DSL) 要はとある目的のために設計された言語のこと Rspec でいうと、プログラムの振舞を記述するという目的のために作られた言語、ということ
振舞い クラスやメソッドの挙動のこと 挙動を仕様( spec )と言い換えても OK
テストを作るのと何が違うの? テスト駆動だと・・・ 仕様を決定->それをもとにテストを作成->テストが通る実装を行う 振舞い駆動だと・・・ 仕様を定義( spec を記述) -> Rspec を通る実装を行う Rspec だと2ステップで分かりやすい (つってもそこまで違いはないような気もする・・・)
RSpec の書き方は? 例えばこんな感じ
Rspec の書き方は? (2) describe と context 振舞いをざっくり説明 describe で対象、 context で状況を記述 (どっちも直接何かをしてくれるわけではないよ) ネスト可能
Rspec の書き方は? (3) before テスト前に行う処理を記述 subject テスト対象を記述 it テストを記述
実行するとこんな感じ Describe や it で書いた文言がそのまま出てます。 ※ この出力が仕様書のようになるのが理想
it と its の違い
it と its の違い (2) Its は subject で指定した要素の属性を指定できて、2種類の使い方がある シンボルで指定(さっきの。) 文字列で指定 文字列だと↓みたいにネストでの指定もできる subject {@empty_array}  its ('methods.size') { should == 248 }
matcher actual.should matcher(expected) actual.should_not matcher(expected)   should は、 actural を matcher の条件を満たすことを期待するという意味。 should と should_not は Object に定義されている。
matcher(2) 演算子マッチャ (>,<,==…) ビルトインのマッチャ( have().items,include(),match()… ) be_xxxx(be_empty… メソッドの前に be_ ) be_true と be_false have_xxx(has_xxx)  {:a => &quot;A&quot;}.has_key?(:a) カスタムマッチャ(自分で定義するマッチャ)
stub コールに対して定義された結果を返す Model(activerecord) に対してよく使う ・ User#create がコールされたときは User.new を返す。 ・ User#find_by_name がコールされたときは、   factory_girl で定義されている「 default_user 」を返す。 ※ factory_girl については後ほど。
mock コールに対して定義された結果を返して且つコールされたことを検証する spec 実行結果
Webmock http リクエストを乗っ取ってレスポンスを指定できる Http リクエストするのにどんなライブラリ使ってても stub できるので便利 stub_request の括弧内が条件。 この条件にマッチするリクエストを行われたら、 実際にリクエストする代わりに to_return に記述したレスポンスを返却する。
factory_girl Test 用のモデルデータを生成してくれる ${PROJECT_HOME}/spec/factories 配下にモデルに対応する rb ファイルを作成 モデル間の関連を定義できたりする
factory_girl(2) Factory ファイル Spec ファイル Factory(: ~ ) もしくは Factory.create(: ~ ) で DB 登録。 一部だけデータ変えることも可能。 インスタンスを作りたいだけなら Factory.build(: ~ ) で。 定義したものを継承( parent 指定)してさらに定義とかできる。
database_cleaner Factory_girl とかで DB 登録したデータを自動で消してくれる。 @ran_tan 曰く、「デフォで消してくれますよ?」とか言ってたけど自分の環境だと消えないので仕方なく導入。 spec_helper.rb に削除するタイミングを記述。
Database_cleaner(spec_helper.rb)
:each, :all before,after のデフォルトは :each :each は it それぞれに対して処理される :all は親ノードに対して一回のみ処理される
:each, :all(2) routes.rb に定義していれば、 contoller の spec では「 get :index 」みたいにコールできたり、「 controller.hoge 」みたいにテスト対象を controller という変数で参照できるが、これは it 内か before(:each) のみ。 before(:all) だと routes の読み込みが終わってないっぽい?
参考文献 WEB+DB PRESS vol.61 特集 2 Rails3 テスト最前線 るびま http:// jp . rubyist .net/magazine/?0021-Rspec#l29   t-wada の日記 http://d. hatena . ne . jp / t-wada /20100228/p1   Func09 http://www. func 09.com/ wordpress /archives/532
おわり。

Rspec