2016-04-24 8 views
0

このエラーの解決には問題があります。私はcontroller_specのどの部分が間違って書かれているのか分かりません。助けてください!rspecコントローラのテスト: "予想される#カウントは-1で変更されましたが、0によって変更されました。"

ルート

Rails.application.routes.draw do 
    resources :cases, only: [:index, :show, :new, :create, :edit, :update] do 
    resources :links, only: [:create, :destroy] 
    end 
end 

コントローラ

class LinksController < ApplicationController 

    before_action :prepare_case 

    def destroy 
    @link = @case_file.links.find(params[:id]) 
    @link.destroy 
    redirect_to case_path(@case_file) 
    end 

    private 

    def prepare_case 
    @case_file = CaseFile.find(params[:case_id]) 
    end 
end 

スペック/工場

FactoryGirl.define do 

    factory :link do 

    case_file 
    url 'www.google.com' 

    trait :invalid do 
     case_file nil 
     url '' 
    end 
    end 
end 

スペック/コントローラ

require 'rails_helper' 

RSpec.describe LinksController, type: :controller do 

    let(:user) { build(:user) } 
    before { login_user user } 
    #for user log in 

    let(:case_file) { create(:case_file) } 
    let(:link) { create(:link, case_file: case_file) } 

    describe "DELETE destroy" do 
    it "deletes a link" do 
     expect { delete :destroy, id: link.id , case_id: case_file }. 
     to change(Link, :count).by(-1) 
     expect(response).to redirect_to(case_path(case_file)) 
    end 
    end 
end 

エラーメッセージ

$ RSpecのスペック/コントローラ/ links_controller_spec.rb ... F

障害:

1)LinksController削除を破壊DELETEリンク 失敗/エラー: expect {delete:destroy、id:link.id、case_id:case_file }。 .by(-1)#countが-1で変化していることではなく、0 #の./spec/controllers/links_controller_spec.rb:28:in `によって変更された期待

:(カウント数のリンクを)変更する

RSpecの./spec/controllers/links_controller_spec.rb:1.18秒で完成

'内のブロック(3段階) 4例、1つの失敗

失敗例(ファイルがロードする5.03秒かかりました) :27#LinksController DELETE destroyリンクを削除します

+0

は、これらの宝石を使用しています –

答えて

3

これは古典的な間違いです(ただし、重複はありません)。 letを使用すると、rspecは関連するブロックのみを実行します。その場合は、Linkオブジェクトを最初に参照するときに作成します。

結果として、リンクはexpectに渡されたブロック内で作成され、破棄されます。カウントは変化せず、テストは失敗します。

あなたがする必要があるのは、テストの早い段階でlinkです。テストのどこかでlinkにランダム呼び出しを追加するのではなく、letの代わりにlet!を使用すると、rspecはサンプルが実行され、テストに合格する前にオブジェクトを作成します。これはまったく同じことです

before(:example) { link } 
1

回答が非常に役に立ちました。私はletとletの違いに関するより多くの情報を見つけました! here。ここでの鍵は、letは遅延評価されていることです。

この場合、let!メソッドを手動で呼び出す必要はありません。 宝石 'RSpecのレール'、 '〜> 3.0' 宝石 'shoulda-マッチャ'、 '〜> 3.1' 宝石 'factory_girl_rails':

関連する問題