1

私は Rspec2、Rails 3 でコントローラーのテストに取り組んでいます。基本的には、通信コントローラーに編集アクションがあるため、誰かが一括メールを編集したい場合は、ドラフト モードで編集できます。承認または送信された場合は、編集できません。

私のコントローラーは次のようになります

class CommunicateController < ApplicationController
before_filter :setup

require_role 'view_communication'
#require_role 'edit_communication', :only => [:new, :edit, :create, :update, :destroy] Role not implemented
require_role 'approve_communication', :only => :approve
require_role 'send_communication', :only => :distribute

 ...

# GET /communications/1/edit
def edit
  if @communication.status == 'Sent' || @communication.status == 'Approved'
    flash[:error] = 'Cannot edit communication once it has been either approved or sent.'
    redirect_to(communicate_path(@communication))
 end
end

 ...

private
  def setup
    @communication = current_account.communications.find(params[:id]) if params[:id]
  end
end

今では本番環境で動作し、すべてがクールです。問題は、私がそれをテストしなければならないときです。

私のテストは次のようになります。

describe CommunicateController, "#edit" do
  context "when i am editing a pre approved bulk email" do
  before(:each) do
    @account = FactoryGirl.create(:account)
    @user = FactoryGirl.create(:superuser, :accounts => [@account])
    controller.stub(:current_account).and_return(@account)
    @supplier = FactoryGirl.create(:supplier, :account => @account)
    @other_supplier = FactoryGirl.create(:supplier, :account => @account)
    @supplier_report = FactoryGirl.create(:supplier_report, :reportable => @account)
    @communicate = FactoryGirl.create(:communication, :account => @account, :supplier_report => @supplier_report)
    controller.stub(:setup).and_return(@communicate)
  end

  it "denies edit access if the bulk email is sent" do
    @communicate.status = 'Sent'
    get :edit, :id => @communicate.id 
    response.should redirect_to(communicate_path(@communicate))
  end

  it "denies edit access if the bulk email has been approved" do
    @communicate.status = 'Approved'
    get :edit, :id => @communicate.id
    response.should redirect_to(communicate_path(@communicate))
  end

  it "allows edits to Draft bulk email" do
    @communicate.status = 'Draft'
    get :edit, :id => @communicate.id
    response.should redirect_to(edit_communicate_path)
  end

 end
end

ご覧のとおり、この特定のテスト用の環境のセットアップは、すべての要件で非常に複雑です。しかし、テストを実行すると、次のエラーが表示されます。

Failure/Error: response.should redirect_to(communicate_path(@communicate))
Expected response to be a redirect to <http://test.host/communicate/1> but was a redirect to <http://test.host/>

しかし、3 つのテストすべてで同じエラーが発生します。コードは機能しており、テストは正しいルートを探しているようですが、ルートルートを探す理由がわかりません。

これが単純な間違いである場合は申し訳ありませんが、私はレールで数か月しかプログラミングしていませんが、これは実際にはrspecでの最初のコントローラーテストであるため、何を探すべきか、またはテストが良好な状態であるかどうかさえわかりません。

どんな助けや指導も大歓迎です

4

1 に答える 1

1

のようなことをする

grep -ri "redirect_to root_path" ./

アプリディレクトリ内で、ルートパスへのリダイレクトがある場所を確認し、それを使用してデバッグを試すことができます

それらのアクションは実際に呼び出されていますか? 編集アクションの最初に「print 'enters!'」を入力します。コンソールに何も出力されないのではないかと思います。あなたのテストに欠けている

ところで(仕様が良好な状態かどうかも尋ねるように)、モデルをモックして、必要なメソッドをスタブする必要があります。

(コントローラー上)

def edit
  unless @communication.can_edit?
    flash[:error] = 'Cannot edit communication once it has been either approved or sent.'
    redirect_to(communicate_path(@communication))
  end
end

(モデル上)

def can_edit?
  ('Sent','Approved').include? status
end

(そして仕様について)

before(:each) do
  account = mock(:account)
  controller.stub(:current_account).and_return(account)
  communication = mock(:communication)
  communication.stub(:can_edit? => false) #you can override this with true on the allow test
  controller.stub(:setup).and_return(communication)
end

次に、これら2つの拒否テスト(送信済みと承認済み)を通信仕様に移動し(「ステータスが送信済みの場合はfalseを返す」など)、コントローラーテストは「通信できない場合はアクセスを拒否します」にする必要があります編集された「やります」

それが役に立てば幸い

編集:また、コントローラーのアクションで @communication を使用するだけの場合、仕様は次のようなヘルパーメソッドが必要になると思います:

def current_communication
  @communication
end

setup メソッドをスタブ化しているため、@communication 割り当ては実行されず、直接使用すると @communication は nil になります。

于 2012-08-13T16:56:40.017 に答える