2

私はMichaelHartlのRubyonRails 3チュートリアル(オンライン版ではなく、本の初期のKindle版)の第9章の終わりにいて、失敗した統合テスト(users_spec.rb)に遭遇しました。私はしばらく探していましたが、これまでに見つけた提案のどれも私のためにうまくいきませんでした。第1版と第2版の両方のチュートリアルのソースコードをダウンロードしましたが、正常に動作しているため、アプリケーションの構成に問題があるように見えますが、レール初心者としては、干し草の山で針を探しているように感じます。だからどんな助けでも大歓迎です。

エラーメッセージ:ActionController :: RoutingError:No route matchs [GET] "/ signout"

users_spec.rbにはこれが含まれています

    ...
       describe "success" do
          it "should sign a user in and out" do
             user = FactoryGirl.create(:user)
             visit signin_path
             fill_in :email, :with => user.email
             fill_in :password, :with => user.password
             click_button
             controller.should be_signed_in
             click_link "Sign out"
             controller.should_not be_signed_in
          end
       end
    ...

私のapplication.html.erbは次のようになります

    <!DOCTYPE html>
    <html>
    <head>
      <title><%= @title %></title>
      <%= javascript_include_tag 'default' %>
      <%= csrf_meta_tags %>
      <%= render 'layouts/stylesheets' %>
    </head>
    <body>
      <div class='container'>
        <%= render 'layouts/header' %>
        <section class = "round">
          <% flash.each do |key, value| %>
            <div class="flash <%= key %>"><%= value %></div>
          <% end %>
          <%= yield %>
        </section>
        <%= render 'layouts/footer' %>
        <%= debug(params) if Rails.env.development? %>
      </div>
    </body>
    </html>

私のapplication_controller.rbは次のようになります

    class ApplicationController < ActionController::Base
      protect_from_forgery
      include SessionsHelper
    end

私のapplication.jsは次のようになります

    // This is a manifest file that'll be compiled into application.js, which will include all the files
    // listed below.
    //
    // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
    // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
    //
    // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
    // the compiled file.
    //
    // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
    // GO AFTER THE REQUIRES BELOW.
    //
    //= require jquery
    //= require jquery_ujs
    //= require_tree .

_header.html.erbファイルにはこれが含まれています

    ...
      <% if signed_in? %>
      <li><%= link_to "Sign out", signout_path, :method => :delete %></li>
      <% else %>
    ...

私のroutes.rbにはこれが含まれています

    ...
      get "sessions/new"

      resources :users
      resources :sessions, :only =>[:new, :create, :destroy]

      match '/contact', :to => 'pages#contact'
      match '/about', :to => 'pages#about'
      match '/help', :to => 'pages#help'
      match '/signup', to: 'users#new'

      match '/signin', to: 'sessions#new'
      match '/signout', to: 'sessions#destroy', via: :delete

      root :to => 'pages#home'
    ...

私のsessions_controller.rbにはこれが含まれています

    ...
      def destroy
        sign_out
        redirect_to root_path
      end
    ...

session_helper.rbにはこれが含まれています

    ...
      def sign_out
        cookies.delete(:remember_token)
        @current_user = nil
      end
    ...

これは、レーキルートを実行したときに得られるものです

    sessions_new GET    /sessions/new(.:format)   sessions#new
           users GET    /users(.:format)          users#index
                 POST   /users(.:format)          users#create
        new_user GET    /users/new(.:format)      users#new
       edit_user GET    /users/:id/edit(.:format) users#edit
            user GET    /users/:id(.:format)      users#show
                 PUT    /users/:id(.:format)      users#update
                 DELETE /users/:id(.:format)      users#destroy
        sessions POST   /sessions(.:format)       sessions#create
     new_session GET    /sessions/new(.:format)   sessions#new
         session DELETE /sessions/:id(.:format)   sessions#destroy
         contact        /contact(.:format)        pages#contact
           about        /about(.:format)          pages#about
            help        /help(.:format)           pages#help
          signup        /signup(.:format)         users#new
          signin        /signin(.:format)         sessions#new
         signout DELETE /signout(.:format)        sessions#destroy

私のgemfileは次のようになります

    source 'https://rubygems.org'

    gem 'rails', '3.2.8'

    gem 'pg'
    gem 'gravatar_image_tag'
    gem 'jquery-rails'

    group :development do
      gem 'rspec-rails'
      gem 'annotate'
    end

    group :test do
      gem 'rspec'
      gem 'webrat'
      gem 'spork'
      gem 'factory_girl_rails'
    end

bundler installを実行すると、これが出力として表示されます。

    Using rake (0.9.2.2)
    Using i18n (0.6.1)
    Using multi_json (1.3.6)
    Using activesupport (3.2.8)
    Using builder (3.0.4)
    Using activemodel (3.2.8)
    Using erubis (2.7.0)
    Using journey (1.0.4)
    Using rack (1.4.1)
    Using rack-cache (1.2)
    Using rack-test (0.6.2)
    Using hike (1.2.1)
    Using tilt (1.3.3)
    Using sprockets (2.1.3)
    Using actionpack (3.2.8)
    Using mime-types (1.19)
    Using polyglot (0.3.3)
    Using treetop (1.4.11)
    Using mail (2.4.4)
    Using actionmailer (3.2.8)
    Using arel (3.0.2)
    Using tzinfo (0.3.33)
    Using activerecord (3.2.8)
    Using activeresource (3.2.8)
    Using annotate (2.5.0)
    Using diff-lcs (1.1.3)
    Using factory_girl (4.1.0)
    Using rack-ssl (1.3.2)
    Using json (1.7.5)
    Using rdoc (3.12)
    Using thor (0.16.0)
    Using railties (3.2.8)
    Using factory_girl_rails (4.1.0)
    Using gravatar_image_tag (1.1.3)
    Using jquery-rails (2.1.3)
    Using nokogiri (1.5.5)
    Using pg (0.14.1)
    Using bundler (1.2.0)
    Using rails (3.2.8)
    Using rspec-core (2.11.1)
    Using rspec-expectations (2.11.3)
    Using rspec-mocks (2.11.3)
    Using rspec (2.11.0)
    Using rspec-rails (2.11.4)
    Using spork (0.9.2)
    Using webrat (0.7.3)

おそらく興味深いのは、Railsを介してアプリケーションを実行すると、アプリケーションも失敗するため、Webratや統合の失敗だけではないということです。firbugのhtmlソースを見ると、表示されると予想されるjavascriptがそこにないことがわかります。

    <script type="text/javascript" src="/assets/jquery.js?body=1">
    <script type="text/javascript" src="/assets/jquery_ujs.js?body=1">

サインイン状態

「サインアウト」をクリックすると、これが結果になります サインアウトに失敗する

4

2 に答える 2

0

あなたが webrat を使用していることに気付きました:

    group :test do
      gem 'rspec'
      gem 'webrat'
      gem 'spork'
      gem 'factory_girl_rails'
    end

まだ webrat を使用しているそのチュートリアルの最後のバージョンは 3.0 であり、参照しているテストのバージョンはhereからのものです。これは、動作するようにテストされたGemfileを使用せずに、古い 3.0 チュートリアルに従おうとしていることを意味します。

カピバラは次期メジャーバージョンで挙動が変わるため、扱いに問題があるかもしれませんが、問題ありません。data-method: :delete

于 2012-11-09T03:09:11.450 に答える
0

エグゼクティブサマリー

カピバラの代わりにwebratを使用しています。これにより、以下で説明する問題が発生した理由が説明されます。変化する:

gem 'webrat'

gem 'capybara'

Gemfile で、DELETE リクエストの JavaScript クリック ハンドラが正常に動作するはずです。

関連する問題のより詳細な議論については、以下の私の元の回答を参照してください。

元の答え

これはトリッキーです。問題は、テストでjavascriptがオンになっていないことです。

いくつかの背景: Rails はjquery-ujsと呼ばれるスクリプト アダプターを使用して、強制確認ダイアログ (レコードを削除しようとしたときに表示される「よろしいですか?」というメッセージ) や、ハイパーリンクからの非 GET 要求 (そのため、 「削除」リンクをクリックすると、ブラウザから DELETE リクエストが送信されます)。

routes.rb には、次のものがあります。

signout DELETE /signout(.:format)        sessions#destroy

つまり、DELETE リクエストが URL/signoutに届いたら、ユーザーをサインアウトします。ただし、デフォルトでは、ページ上の URL へのリンクをクリックすると/signout、ブラウザは DELETE リクエストではなく GET リクエストを送信します。

method: destroyここへの呼び出しにオプションを含める場合link_to:

link_to "Sign out", signout_path, :method => :delete

これは、ビュー内のリンクの属性に属性を追加するよう Rails に指示することですdata-method="delete"(実際にレンダリングされた HTML をチェックして、これが正しいことを確認してください)。この属性はフラグのようなものです。jquery-ujs に、この要素のクリックを GET から DELETE に変えるクリック ハンドラを追加するように指示します。詳細については、この記事を参照してください。Hartl がこの点について脚注で言及していることにも注意してください。

しかし、この場合に JavaScript が有効になっていないとどうなりますか? ラスト クリック ハンドラーは追加されず、ブラウザーはそのリンクを/signoutページ上の他のリンクと同じように扱うため、クリックするとその URL に GET 要求が送信されます。ただし、Rails には への GET リクエストのパスがないため/signout、エラーが発生します。

ActionController::RoutingError: No route matches [GET] “/signout”

ここが問題の原因です。

js: true解決策として、次のように、JavaScriptを有効にするオプションをテストに追加できるはずです。

it "should sign a user in and out", js: true do
  ...
end

デフォルトの JavaScript ドライバーである Selenium を使用している場合、これにより実際にブラウザー ウィンドウが開きます。ウィンドウなしで js テストを実行するには、capybara-webkit gem を Gemfile に追加し、 を使用してドライバーを設定しますCapybara.javascript_driver = :webkit。Rspec リクエスト仕様での JavaScript の使用の詳細については、JavaScript のテストに関するこの Railscastのセクションを参照してください。

于 2012-11-08T21:37:16.397 に答える