17

私は自分のコントローラーをテストし、関心の分離を維持しようとしています。

最初の懸念は、「誰がどのアクションを実行できるか」です。認証にauthlogicを使用
し、承認にbe9のacl9を使用しています。しかし、これは重要ではありません。私の承認に関する懸念はすべて、で処理されます。私はこれに似た何かによってそのようなものをテストしています:before_filterbefore_filter

describe SomeModelsController, "GET to index (authorization)" do
  before(:each) do
    @siteadmin = mock_model(User)
    @siteadmin.stub!(:has_role?).with("siteadmin", nil).and_return(true)
  end

  it "should grant access to a siteadmin" do
    controller.should_receive(:current_user).at_least(:once).and_return(@siteadmin)
    get :index
    response.should be_success
  end
end

この仕様は問題なく機能しています。

さて、2番目の懸念は「アクションはそれがすることになっていることをするのか?」です。
これには、承認の確認は含まれません。最良/最もクリーンな解決策は、それをすべて一緒にスキップしてbefore_filter、次のようなことを行うことです。

describe SomeModelsController, "GET to index (functional)" do
  it "should find all Models" do
    Model.should_receive(:find).with(:all)
  end
end

どのロールのどのユーザーが最初にログインする必要があるかを心配する必要はありません。今、私はそれをそのように解決しました:

describe SomeModelsController, "GET to index (functional)" do
  before(:each) do
    @siteadmin = mock_model(User)
    @siteadmin.stub!(:has_role?).with("siteadmin", nil).and_return(true)
    controller.stub!(:current_user).and_return(@siteadmin)
   end
  
  it "should find all Models" do
    Model.should_receive(:find).with(:all)
  end
end

私のsiteadminがインデックスアクションにアクセスする権利をもう持っていないと判断した場合、1つの仕様、つまりそのような場合に破る必要のある仕様だけでなく、まったく関係のない2番目の仕様も破ることになります。

これは基本的に小さな問題ですが、誰かが(エレガントな)解決策を思い付くことができれば素晴らしいと思います!

4

3 に答える 3

34

beforeフィルターをスキップするには:

controller.class.skip_before_filter :name_of_method_used_as_before_filter

1つの注意点(ドキュメントに記載)は、これはメソッド参照フィルターでのみ機能し、procでは機能しないことです。

または、スタブすることもできますcurrent_user.has_role?

describe SomeModelsController, "GET to index (functional)" do
  before(:each) do
    controller.current_user.stub!(:has_role?).and_return(true)
  end

  it "should find all Models" do
    Model.should_receive(:find).with(:all)
  end
end
于 2009-11-20T18:08:27.573 に答える
0

古い質問ですが、最近これを解決する必要がありました。これはRails3.1でのみ機能します。以前のバージョンでは_process_action_callbacksfilter_chain(テストされていない)に置き換える必要があります。

次のように、一致するProcをフィルターチェーンから簡単に削除できます(Test :: Unitの例):

class RandomControllerTest < ActionController::TestCase
  def setup
    @controller.class._process_action_callbacks.each do |f|
      @controller.class._process_action_callbacks.delete(f) if f.raw_filter.to_s.match(/**<match for your proc>**/)
    end
  end
end
于 2011-11-27T16:55:13.417 に答える
-9

GETリクエストを行わないのはどうですか?コントローラメソッドを単独で呼び出してみてください。

controller.index
于 2009-11-24T06:28:14.197 に答える