【问题标题】:Testing methods using gon with rspec使用 gon 和 rspec 的测试方法
【发布时间】:2014-07-28 13:30:03
【问题描述】:

我有一个函数可以在 gon 的帮助下向 js 发送一个变量。

def calc_foo
  # calculate foo
  gon.foo = foo
end

我想测试这个函数,即使用 rspec 确保方法返回正确的值。

it "should return bar" do
  foo = @foo_controller.calc_foo
  expect(foo).to eq(bar)
end

但是,当测试用例到达将变量发送到 gon 的行时,我收到以下错误消息。

Failure/Error: foo = @foo_controller.calc_foo
 NoMethodError:
   undefined method `uuid' for nil:NilClass

我检查了 foo 的值,它不是 Nil,所以 gon 必须是 Nil。 我相信错误是我没有正确地包含 gon。这是我的 Gemfile 的 rspec 部分

#rspec-rails includes RSpec itself in a wrapper to make it play nicely with Rails. 
#Factory_girl replaces Rails’ default fixtures for feeding test data
#to the test suite with much more preferable factories.
group :development, :test do
  gem 'rspec-rails'
  gem 'factory_girl_rails'
  gem 'capybara'
  gem 'gon'
end

那么我怎样才能让 rspec 与 gon 配合得很好呢? (我也尝试在我的规范文件中包含 gon,但没有成功)

【问题讨论】:

  • 使用 -b 运行 rspec 以查看发生错误的位置。
  • @DaveSchweisguth 我运行 rspec -b 得到以下结果:/gems/gon-5.1.2/lib/gon/helpers.rb:49:in gon_request_uuid' /gems/ruby-2.1.2@webgraphs/gems/gon-5.1.2/lib /gon/helpers.rb:32:in gon'

标签: ruby-on-rails rspec gon


【解决方案1】:

在控制器规范(gon 所属的地方)中,您需要提出实际请求来绕过您的问题:

RSpec.describe ThingiesController do
  let(:gon) { RequestStore.store[:gon].gon }

  describe 'GET #new' do
    it 'gonifies as expected' do
      get :new, {}, valid_session # <= this one
      expect(gon['key']).to eq :value
    end
  end
end

如果您不想坚持使用某些controller 或action 来获取与gon 相关的规范(假设您在ApplicationController 中有一个与gon 相关的方法),您可以使用@ 987654321@方法:

RSpec.describe ApplicationController do
  let(:gon) { RequestStore.store[:gon].gon }

  controller do
    # # Feel free to specify any of the required callbacks,
    # # like
    # skip_authorization_check
    # # (if you use `CanCan`) 
    # # or
    # before_action :required_callback_name

    def index
      render text: :whatever
    end
  end

  describe '#gon_related_method' do
    it 'gonifies as expected' do
      get :index
      expect(gon['key']).to eq :value
    end
  end
end

我有很多 controller 和 request/integration 规范,可以确认 gon 在那里表现良好,只要您提出实际请求。

但是,尽管情况有所不同,但我仍然遇到与您类似的问题(从 controller 规范中包含的 shared_examples 发出请求)。我已经打开了相关的issue,欢迎加入讨论(任何有兴趣的人)。

【讨论】:

    【解决方案2】:

    我测试控制器是否传递了正确的东西以进入请求规范。

    控制器设置一个对象数组——例如,gon.map_markers = [...]

    我的请求规范通过正则表达式提取 JSON(.split() 和 match_array 处理与顺序无关的数组):

    ....
    
    # match something like
    #   gon.map_markers=[{"lat":a,"lng":b},{"lat":c,"lng":d},...];
    # and reduce/convert it to
    #   ['"lat":a,"lng":b',
    #    '"lat":c,"lng":d',
    #    ...
    #   ]
    actual_map_markers = response.body
                         .match('gon.map_markers=\[\{([^\]]*)\}\]')[1]
                         .split('},{')
    
    expect(actual_map_markers).to match_array expected_map_markers
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多