2017-02-27 10 views
0

私はRoRアプリケーションをテストしようとしています。私は私のコントローラでActionController :: RoutingErrorを引き起こすためにテストするとき、私はエラーを以下の取得: ガット1つの故障と1つのその他のエラー:が必要です。ActionController :: RoutingErrorが、レールアプリでブロックが指定されていませんでしたrspec

2.1) Failure/Error: expect(visit meters_path).to raise_error(ActionController::RoutingError) 
     expected ActionController::RoutingError but was not given a block 
     # ./spec/integration/meter_behavior_spec.rb:70:in `block (2 levels) in <top (required)>' 

2.2) Failure/Error: raise ActionController::RoutingError.new('Not Found') 

     ActionController::RoutingError: 
     Not Found 

は理由は何ですか? これは、テスト宝石の私のリストです:

group :development, :test do 
    gem 'factory_girl_rails' 
    gem 'faker' 
    gem 'rspec-rails' 
end 
group :test do 
    gem 'capybara' 
    gem 'database_cleaner' 
    gem 'launchy' 
    gem 'selenium-webdriver', '2.53.4' 
    gem 'capybara-webkit' 
    gem 'shoulda-matchers', '~> 3.1' 
end 

私のspecファイルは、私はあなたが単に会っ訪問渡す必要があると考えてい

meter_behavior_spec.rb

scenario 'a visitor cannot to view meters pages', driver: :webkit do 
    user = FactoryGirl.create(:client1) 
    user.meters.create(attributes_for(:meter))   
    expect(visit meters_path).to raise_error(ActionController::RoutingError) 
    end 

meters_controller.rb:

before_action only: :index do 
    access_allowed_for(['Client']) 
    end 
    # GET /meters 
    # GET /meters.json 
    def index 
    respond_to do |format| 
     format.json { render json: MetersDatatable.new(view_context, current_user) } 
     format.html 
    end 
    end 

application_controller.rb:

def access_allowed_for(statuses_ary=[]) 
    statuses_ary << 'Admin' 
    if !user_signed_in? || statuses_ary.exclude?(current_user.try(:status)) 
     raise ActionController::RoutingError.new('Not Found') 
    end 
    end 

答えて

1

Jean-Christopheの答えで指摘されている最初の問題は、raise_errorのマッチャーがブロックを必要としていることです。 2番目の問題は、フィーチャーテストではなく、実際にコントローラーテスト(カピバラ駆動ではなく)でテストした方が良いかどうかをテストすることです。

あなたが機能検査でこれをテストすることを主張した場合、あなたは

  1. を確認する必要があるいくつかの事はあなたがエラーをキャッチし、生成されたテスト環境内のすべての宝石を持っていないことを確認してくださいがあります素敵な/詳細なエラーページ。これには、web_consolebetter_errorsなどの宝石が含まれます。これらの宝石は開発環境内になければなりません。

  2. は、あなたのテストの設定あなたがブロック内で二カピバラ文を追加する必要があるかもしれません

  3. Capybara.raise_server_errors = trueを設定していることを確認してください。これは、Capybaraがテストとは別のスレッドでアプリケーションを実行し、訪問呼び出しが非同期で発生する可能性がある(使用するドライバによって異なる)ためです。つまり、訪問呼び出しが戻ったときに実際にエラーが発生していない可能性があります。 2番目の呼び出しをcapybaraメソッドに追加することで、訪問が終了するまで少し待ってから、サーバー/アプリケーションスレッドでエラーが発生したことを検出し、そのエラーをテストスレッドで再発生させます。

    expect{ 
        visit meters_path 
        page.has_text? 'Random text' # only here to give time for app to raise error 
    }.to raise_error(ActionController::RoutingError) 
    
+1

1私は私のgemfileに 'web-console'と' better errors'の両方の宝石があることを確認しましたが、どちらも 'development'グループにあります。 2次に、 'Capybara.raise_server_errors = true'文字列を' spec/support/capybara.rb'ファイルに追加しましたが、もう一度エラーが出ました。 3最後に 'page.has_text? 'ステートメントを追加しました。ありがとうございました。 –

+0

私は 'Capybara.raise_server_errors = true'文字列にコメントするときは、うまく動作するものをテストします。 –

+0

@ЭрикКеубасовはい - それは本当に、私はちょうどどこかに偽にリセットしていないことを確認したいと思った。 –

1

そのようなブロックとしてではなく引数としてers_path、:

expect{visit meters_path}.to raise_error(ActionController::RoutingError) 

は参照してください:それが動作するかどうか

https://www.relishapp.com/rspec/rspec-expectations/v/2-2/docs/matchers/expect-error

は教えてください。

+0

おかげで、それは助けにはなりませんでした。 1.1.3エラー/エラー:{visit meters_path} .to raise_error(ActionController :: RoutingError)を期待する ActionController :: RoutingErrorが発生しましたが、何も起こっていません。 1.2)失敗/エラー:ActionController ::を上げてください。 RoutingError.new( 'Not Found') –

+0

それでも、正しい方向に進んでいます。最初の失敗はテストコードではなく、テストしているコードになりました。コントローラーアクションまたはaccess_allowed_forメソッドのいずれかでエラーが自動的に発生した場合(つまり、条件の外にある場合)にテストは合格しますか。これは募金そのものの問題を排除します。あなたの条件に関しては、どのようなステータスがあなたの行いますか? ( 'client'? 'Client'?) –

+0

私のコントローラでエラーが発生すると、同様のエラー/エラーメッセージが表示されます。 client1には「クライアント」ステータスがあります。とにかくありがとうございました。 –

関連する問題