1

コントローラーでカスタム検索メソッドの動作をテストしようとしています:

    #RecordingsController
    def search
      # raise params.inspect
      @search = params[:search]
      searches = []
      searches2 = []
      for n in 1..5
        searches << @search["date(#{n}i)"].to_i
        searches2 << @search["date2(#{n}i)"].to_i
      end
      start_date = date_format(*searches)
      end_date = date_format(*searches2)
      conditions = []
      conditions << "agent like '%#{@search["agent"]}%'" unless @search["agent"].blank?
      conditions << "phone like '%#{@search["phone"]}%'" unless @search["phone"].blank?
      conditions << "date between '#{start_date}' and '#{end_date}'"

      @recordings = Recording.where(conditions.join(" AND ")).order('date ASC')
      if @recordings.blank?
        redirect_to("/", alert: "No results were found for this search. Please try again.")
      else
        render "recordings/search"
      end
    end

次のレイアウトを使用します。

    #recordings_controller_spec.rb
    describe RecordingsController do
      describe "POST #search" do
        context "with valid attributes" do
          it "assigns a new search to @search" do
            search = @recording_search
            get :search, @recording_search
            assigns(:search).should eq(search)
          end
          it "populates an array of recordings"
          it "renders the :search view"
        end
      end
    end

私が得た最も遠いものは、フォームの params ハッシュが何であるかを模倣するハッシュを構築しようとしています

    #params hash
    params = {"search" => { "date_1i" => "2012", "date_2i" => "1", ... "date2_5i" => "00" } }

ここで、date_#{n}i は開始日 [年、月、日、時、分]、date2_#{n}i は終了日です。ここに投稿された回答に従って、params ハッシュを通常のハッシュだけで模倣しようとしています。コントローラーからわかるように、実際にはパラメーターを #search メソッドに渡しません。私はすべきですか?または、rspec テストで params ハッシュをモックし、my @search@recordings、およびredirect_to/render変数/アクションが実行されているかどうかを判断する方法はありますか? リクエスト仕様でレンダリング/リダイレクトをすでにテストしていますが、可能であればこのメソッドを完全にテストしたいと思います。

4

1 に答える 1

2

指定された一連のパラメーターを使用して検索アクションを取得するコントローラー仕様を生成できる必要があります。これにより、これらのパラメーターが params ハッシュで使用できるようになります。次に、検索がどのように構築され、どの結果が返されるかを確認できます。

describe RecordingsController do
  describe '#search' do
    it 'should return results' do
      get :search, "search" => { "date_1i" => "2012", "date_2i" => "1", ... "date2_5i" => "00" }
      response.should be_ok
      @recordings.map(&:name).should == ['expected1', 'expected2']
    end
  end
end

この例では、いくつかの検索条件をクエリ パラメーターとして使用して検索を実行し、応答が成功したこと (http 200 ステータス) を確認してから、返された録音のリストを抽出し、それらをわかりやすい録音名のリストにマップしようとします (任意のキーを使用できます)。このモデルで) それらを予想される結果のリストと比較します。

このコントローラーで懸念事項を分離すると、このコードの作成/テストが簡単になります。クエリ パラメーターを処理して検索フィルターを構築するヘルパーを作成し、それをコントローラーのレコーディング モデルに渡すことができます。

class RecordingController
  def search
    @search_filter = SearchFilter.for_params(params[:search])
    @recordings = Recording.where(@search_filter).order('date ASC')
    render "recordings/search"
  end
end

class SearchFilter
  # Return search params as a hash for given request params hash
  def self.for_params(params)
    ...
  end
end

これにより、検索フィルターを生成するロジックの単体テストを作成し、コントローラーが検索ロジックとレコーディング モデル コレクションの間で情報を渡すというより単純な操作を行っていることのみを確認できます。また、空の結果を表示するロジックを結果ページのビューに移動し、コントローラーから移動することをお勧めします。

于 2013-02-02T18:53:53.863 に答える