【问题标题】:Rspec request specs and Rails 5Rspec 请求规范和 Rails 5
【发布时间】:2017-04-14 13:51:55
【问题描述】:

我正在开始一个新项目,这是我使用 Rails 5.1.0 的第一个项目。我的第一个请求规范有一个 pb。

describe 'Users', type: :request do
  it 'are created from external data' do
    json_string = File.read('path/to/test_data/user_data.json')
    params = { user: JSON.parse(json_string) }
    headers = { "CONTENT_TYPE" => "application/json" }

    expect do
      post '/api/v1/users', params.to_s, headers
    end.to change {
      User.count
    }.by(1)

    expect(response.status).to eq 200
  end
end

此规范返回错误ArgumentError: wrong number of arguments (given 3, expected 1)official documentation 不多说。

如果我取出 .to_s 并发送哈希,如下所示:

post '/api/v1/users', params, headers

我又遇到了一个错误:

ArgumentError: unknown keyword: user

有什么想法吗?

【问题讨论】:

    标签: ruby-on-rails testing rspec ruby-on-rails-5.1


    【解决方案1】:

    我认为他们最近更改了语法。现在它应该使用关键字 args。所以,是这样的:

    post '/api/v1/users', params: params, headers: headers
    

    【讨论】:

    • 我自己在将应用程序从 Rails 4.2 升级到 5.1 时偶然发现了这个问题。我认为 Rspec 中没有记录更改,因为它只是委托给 Rails 助手,但我的问题是:有没有一种最佳方法可以将规范升级到新格式,或者使用旧格式而不需要太多猴子补丁?我有超过 900 个规格,其中约 150 个因这个问题而失败,还有约 150 个因其他原因而失败,我想尽可能少地更改它们,以便首先发现并解决“真正的”问题。跨度>
    • @wiz:好问题。我不知道这种方式。到目前为止,我一直在手动更改每个事件。
    • 对于它的价值,我将 post 方法追溯到 ActionDispatch::Integration::Session#process,我想这就是 Rails 4 和 5 之间的变化。我不能说我熟悉 Rails 内部,但也许在某个时间点记录了更改?
    【解决方案2】:

    这是Sergio's answer 的一个小附录。如果您要从 Rails 4 升级到 Rails 5,有 大量 测试,并且不太热衷于全部更改 - 至少在升级完成之前不会 - 我找到了一种方法让它们使用旧的方法签名。

    在我的spec_helper 我添加了

    module FixLegacyTestRequests
      def get(path, par = {}, hdr = {})
        process(:get, path, params: par, headers: hdr)
      end
      def post(path, par = {}, hdr = {})
        process(:post, path, params: par, headers: hdr)
      end
      def put(path, par = {}, hdr = {})
        process(:put, path, params: par, headers: hdr)
      end
      def delete(path, par = {}, hdr = {})
        process(:delete, path, params: par, headers: hdr)
      end
    end
    

    然后我为每个测试添加了这个配置:

    RSpec.configure do |config|
      config.before :each do |example|
        extend(FixLegacyTestRequests) # to be removed at some point!
      end
    end
    

    我的测试恢复了工作,我认为它应该是安全的,因为它只应用于当前正在运行的测试并且不应该污染任何 gem 的代码,例如猴子补丁。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2018-10-16
      • 1970-01-01
      • 1970-01-01
      • 2017-04-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多