使用receive_message_chain,和另一个字段

时间:2015-05-28 19:05:07

标签: ruby-on-rails ruby rspec

我正在使用rspec来测试Ruby on Rails应用程序。在我看来,我有这个功能来显示下拉列表。应用程序运行正常但我在尝试运行测试时遇到问题。如何使用receive_message_chainwith,然后再使用receive。我该如何存根这个链?

我的观点:

<%= select_tag "filters[sponsorship_status]",
                  options_for_select(
                     Orphan.distinct.pluck(:sponsorship_status).map {
                        |ss| [Orphan.sponsorship_statuses.key(ss).humanize, ss] },
                    filters[:sponsorship_status]),
     {include_blank: "Any", class: "form-control"} %>

我的测试:

allow(Orphan).to 
          receive_message_chain(:distinct,:pluck)
              .with(:sponsorship_status)
                .receive(:map)
                   .and_return([["sponsorship_status1",
                      orphans_filters[:sponsorship_status].to_s]])

1 个答案:

答案 0 :(得分:0)

我非常同意上面的评论说你应该听你的测试,而不是试图深深地嘲笑。此外,通过检查https://www.relishapp.com/rspec/rspec-rails/docs/view-specs/view-spec中描述的渲染输出来测试视图是典型的。您在此处展示的内容显然不是您的实际测试,而是您为测试设置的其中一个模拟。

也就是说,您的测试代码存在一些问题,最明显的是您尝试将receive期望分开,这是您无法做到的。

作为练习,我创建了下面的代码,以显示RSpec可用于完全模拟您拥有的特定代码的一种方式,尽管我通过在示例中包含测试中的代码来简化测试。实际上,你不能只是存根self来存根各种方法。您必须存根在Rails中调用的实际方法。

module Orphan
end

describe 'code' do
  it 'does what it should' do
    filters_result = double
    options_result = double
    humanize_result = double
    key_result = double(humanize: humanize_result)
    pluck_result = double
    status_double = double
    allow(Orphan).to receive_message_chain(:sponsorship_statuses, :key).with(status_double).and_return(key_result)
    allow(Orphan).to receive_message_chain(:distinct, :pluck).with(:sponsorship_status).and_return(pluck_result)
    allow(pluck_result).to receive(:map) { |&block| [block[status_double]] }
    select_arg_1 = 'filters[sponsorship_status]'
    select_arg_3 = {include_blank: "Any", class: "form-control"}
    options_arg_1 = [[humanize_result, status_double]]
    allow(self).to receive_message_chain(:filters, :[]).with(:sponsorship_status).and_return(filters_result)
    allow(self).to receive(:options_for_select).with(options_arg_1, filters_result).and_return(options_result)
    expect(self).to receive(:select_tag).with(select_arg_1, options_result, select_arg_3)

    select_tag "filters[sponsorship_status]",
               options_for_select(
                   Orphan.distinct.pluck(:sponsorship_status).map {
                       |ss| [Orphan.sponsorship_statuses.key(ss).humanize, ss] },
                   filters[:sponsorship_status]),
               {include_blank: "Any", class: "form-control"}
  end
end