3

これは、Rails 4 の destroy アクション用に自動生成されたテストで、次の仕様の一部ですvehicles_controller.rb

describe "DELETE destroy" do
     it "destroys the requested vehicle" do
       vehicle = Vehicle.create! valid_attributes
        expect {
          delete :destroy, {:id => vehicle.to_param}, valid_session
        }.to change(Vehicle, :count).by(-1)
     end

    it "redirects to the vehicles list" do
      vehicle = Vehicle.create! valid_attributes
      delete :destroy, {:id => vehicle.to_param}, valid_session
      response.should redirect_to(vehicles_url)
    end
end

これがコントローラーにあるもので、これも非常に標準的なものです。

def destroy
  @vehicle = Vehicle.find(params[:id])
  @vehicle.destroy
  flash[:notice] = "Vehicle has been deleted"
  redirect_to vehicles_url
end

これはアプリ自体で問題なく機能します。車両を削除すると、車両は vehicle_url にリダイレクトされ、エントリがデータベースから削除されます。サーバーログも完全に正常に見えます。ただし、仕様を実行すると、次のように失敗します。

1) VehiclesController DELETE destroy destroys the requested vehicle
   Failure/Error: expect {
     count should have been changed by -1, but was changed by 0
   # ./spec/controllers/vehicles_controller_spec.rb:148:in `block (3 levels) in <top (required)>'

2) VehiclesController DELETE destroy redirects to the vehicles list
   Failure/Error: response.should redirect_to(vehicles_url)
     Expected response to be a redirect to <http://test.host/vehicles> but was a redirect to <http://test.host/>.
     Expected "http://test.host/vehicles" to be === "http://test.host/".
   # ./spec/controllers/vehicles_controller_spec.rb:156:in `block (3 levels) in <top (required)>'

テストを失敗させるためにここで何が起こっているのか、誰か教えてもらえますか? 助けてくれてありがとう!

編集:これは、物事に影響を与える可能性のあるフィルターの前に関する追加情報です。vehicle_controller では、gem CanCan を使用しているためload_and_authorize_resource、一番上にあります。このコントローラーは、作成と更新の機能についてもテストされており、これらの仕様は合格しているため、干渉していないと思いました。さらに、アクセス許可に関するメッセージで失敗していませんでした。let(:valid_session) { {} }コントローラー仕様の一番上にあるデフォルトを変更する必要があるのでしょうか? 私が言ったように、削除以外の他のすべてのアクションには問題がなかったので、私はそれをそのままにしておきました。

さらに編集: 以下に提供されているリンクに照らして、仕様を次のように編集しました。

describe "DELETE destroy" do
    it "destroys the requested vehicle" do
      vehicle = Vehicle.create! valid_attributes
      expect {
        delete :destroy, :id => vehicle.to_param, valid_session
      }.to change(Vehicle, :count).by(-1)
    end

    it "redirects to the vehicles list" do
      vehicle = Vehicle.create! valid_attributes
      delete :destroy, :id => vehicle.to_param, valid_session
      response.should redirect_to(vehicles_url)
    end
end

仕様を実行しようとすると、次の構文エラーが表示されます。

/home/kathryn/testing/spec/controllers/vehicles_controller_spec.rb:150: syntax error, unexpected '\n', expecting => (SyntaxError)

delete :destroy行 150 は、変更が行われた で始まる最初の仕様の行を参照します。

4

3 に答える 3

5

ほとんどの場合、認証エラーが発生しています。どちらのテストでもflash[:alert].should == nil、操作の後に追加してみてください。delete認証に問題がある場合は"You are not authorized to access this page."、テストの失敗のようなものが表示されます。

これに対する最大の手がかりは、テストも次のように失敗していることです。

Expected response to be a redirect to <http://test.host/vehicles> but was a
redirect to <http://test.host/>.

認証失敗の一般的な実装では、ルート パスにリダイレクトされます。

, valid_session個人的には、サインインを処理するアプローチは好きではありません。Devise を使用している場合は、Devise のテスト ヘルパーを使用して、適切にサインインする必要があります。例えば

describe VehiclesController do
  include Devise::TestHelpers

  before(:each) do
    sign_in FactoryGirl.create(:user)
  end

  . . .

次に (これは重要です! ) すべてのパラメーターを削除し, valid_sessionます。そうしないと、devise がメソッドで設定したセッションがオーバーライドされますsign_in

これが最も単純な形式です。一部のユーザーが (たとえば) 削除でき、他のユーザーが削除できない場合、これはまだ失敗します。そのため、これらのケースでは、別のdescribe "Admin users can" do...endテスト ブロックを作成し、管理者ユーザーbefore(:each)で which を呼び出します。sign_in

お役に立てば幸いです。幸運を祈ります。

于 2013-10-16T19:46:36.040 に答える
0

Ruby のパーサーは、インライン ハッシュと混同されます。あなたはおそらく欲しい:

    delete :destroy, {:id => vehicle.to_param}, valid_session
于 2013-10-02T01:51:18.563 に答える
0

への引数の受け渡しで問題が発生していますdeletehttp://api.rubyonrails.org/classes/ActionController/TestCase/Behavior.html#method-i-deleteでメソッド定義を参照してください。

次のいずれかを使用できます。

delete :destroy, {id: vehicle.to_param, session: valid_session}

また

delete :destroy, id: vehicle:to_param, session: valid_session

ActionController渡す最後の 2 つのパラメーターで内部で何が起こっているのか正確にはわかりませんが、正しくありません。

于 2013-10-01T22:31:50.290 に答える