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 哈希并确定我@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 状态),然后提取返回的录音列表并尝试将它们映射到友好的录音名称列表(您可以使用任何键在此模型上)将它们与预期的结果列表进行比较。

如果您在此控制器中分离关注点,则编写/测试此代码会更容易 - 您可以编写一个帮助程序来处理查询参数并构建一个搜索过滤器,然后将其传递给控制器​​中的 Recording 模型:

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

这将允许您为生成搜索过滤器的逻辑编写单元测试,并且只验证控制器是否正在执行更简单的操作,即在搜索逻辑和 Recording 模型集合之间传递信息。我还建议将有关显示空结果的逻辑移到结果页面上的视图中并移出控制器。

于 2013-02-02T18:53:53.863 回答