Rspec请求规范和Rails 5

9

我正在开始一个新项目,这是我第一次使用Rails 5.1.0。我在我的第一个请求规范中遇到了问题。

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)。官方文档没有提供太多信息,详见官方文档

如果我去掉.to_s并发送一个哈希值,就像这样:

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

我又遇到了一个错误:
ArgumentError: unknown keyword: user

有什么想法吗?
2个回答

18

我认为他们最近改变了语法。现在应该使用关键字参数。所以,像这样:

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

我在将我的应用程序从Rails 4.2升级到5.1时遇到了这个问题。我认为Rspec中的更改未记录,因为它只是委托给Rails助手,但我的问题是:是否有一种最佳方法来升级规范到新格式,或者使用旧格式而不需要太多的猴子补丁?我有>900个规范,其中150个由于此问题而失败,另外150个由于其他原因而失败,并且我想尽可能少地更改它们,以便首先发现和修复“真正”的问题。 - wiz
@wiz:好问题。我不知道有这样的方法。到目前为止,我一直在手动更改每个出现的地方。 - Sergio Tulentsev
就我所知,我将post方法追踪到了ActionDispatch::Integration::Session#process,我猜这就是Rails 4和5之间的变化。我不能说我熟悉Rails内部,但也许这个变化在某个时候被记录在那里了? - wiz

13

这是对Sergio的回答的一个小补充。如果你正在从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

我的测试又开始工作了,我认为很安全,因为它只适用于当前正在运行的测试,不会污染任何宝石的代码,比如使用猴子补丁。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接