将旧 Rspec 语法转换为新语法

Convert old Rspec syntax into new syntax

我正在使用 APIonRails tutorial 他们有这个:

require 'spec_helper'

describe ApiConstraints do
  let(:api_constraints_v1) { ApiConstraints.new(version: 1) }
  let(:api_constraints_v2) { ApiConstraints.new(version: 2, default: true) }

  describe "matches?" do

    it "returns true when the version matches the 'Accept' header" do
      request = double(host: 'api.marketplace.dev',
                       headers: {"Accept" => "application/vnd.marketplace.v1"})
      api_constraints_v1.matches?(request).should be_true
    end

    it "returns the default version when 'default' option is specified" do
      request = double(host: 'api.marketplace.dev')
      api_constraints_v2.matches?(request).should be_true
    end
  end
end

在一个例子中,但我已经明白这是使用旧语法。

要将其转换为新语法,我正在尝试:

require 'rails_helper'

describe ApiConstraints do
  let(:api_constraints_v1) { ApiConstraints.new(version: 1) }
  let(:api_constraints_v2) { ApiConstraints.new(version: 2, default: true) }

  describe "matches?" do
    it "returns true when the version matches the 'Accept' header" do
      request = double(host: 'api.localhost:3000',
                headers: {"Accept" => "application/vnd.marketplace.v1"})
      expect(request).to match(api_constraints_v1)
    end

    it "returns the default version when 'default' option is specified" do
      request = double(host: 'api.localhost:3000')
      expect api_constraints_v2.matches?(request).to_be true
    end
  end

end

这是我收到的错误:

Failures:

  1) ApiConstraints matches? returns true when the version matches the 'Accept' header
     Failure/Error: expect(request).to match(api_constraints_v1)
       expected #<RSpec::Mocks::Double:0x3feeedaf60c4 @name=nil> to match #<ApiConstraints:0x007fddde50f9b0 @version=1, @default=nil>
       Diff:
       @@ -1,2 +1,2 @@
       -#<ApiConstraints:0x007fddde50f9b0 @default=nil, @version=1>
       +#<RSpec::Mocks::Double:0x3feeedaf60c4 @name=nil>

     # ./lib/spec/api_constraints_spec.rb:11:in `block (3 levels) in <top (required)>'

  2) ApiConstraints matches? returns the default version when 'default' option is specified
     Failure/Error: expect api_constraints_v2.matches?(request).to_be true
     NoMethodError:
       undefined method `to_be' for true:TrueClass
       Did you mean?  to_enum
                      to_s
     # ./lib/spec/api_constraints_spec.rb:16:in `block (3 levels) in <top (required)>'

Finished in 0.0045 seconds (files took 6.52 seconds to load)
2 examples, 2 failures

Failed examples:

rspec ./lib/spec/api_constraints_spec.rb:8 # ApiConstraints matches? returns true when the version matches the 'Accept' header
rspec ./lib/spec/api_constraints_spec.rb:14 # ApiConstraints matches? returns the default version when 'default' option is specified

可能是什么原因造成的?

编辑 1

根据我的 Gemfile.lock,这些是我的相关 gem 的版本:

rspec (3.1.0)
  rspec-core (~> 3.1.0)
  rspec-expectations (~> 3.1.0)
  rspec-mocks (~> 3.1.0)
rspec-core (3.1.7)
  rspec-support (~> 3.1.0)
rspec-expectations (3.1.2)
  diff-lcs (>= 1.2.0, < 2.0)
  rspec-support (~> 3.1.0)
rspec-mocks (3.1.3)
  rspec-support (~> 3.1.0)
rspec-rails (3.1.0)
  actionpack (>= 3.0)
  activesupport (>= 3.0)
  railties (>= 3.0)
  rspec-core (~> 3.1.0)
  rspec-expectations (~> 3.1.0)
  rspec-mocks (~> 3.1.0)
  rspec-support (~> 3.1.0)
rspec-support (3.1.2)
rubyzip (1.2.0)
selenium-webdriver (2.53.0)
  childprocess (~> 0.5)
  rubyzip (~> 1.0)
  websocket (~> 1.0)
shellany (0.0.1)
shoulda (3.5.0)
  shoulda-context (~> 1.0, >= 1.0.1)
  shoulda-matchers (>= 1.4.1, < 3.0)
shoulda-context (1.2.1)
shoulda-matchers (2.8.0)
  activesupport (>= 3.0.0)

我应该使用什么正确的新语法来实现与原始代码相同的功能?

改变

expect request.to eq(api_constraints_v1)

expect(request).to eq(api_constraints_v1)

在其他规范中也有同样的问题...

expect 是一种方法,您可以向其提供期望正在进行的事情(即 request)...

request 方法获得结果后 - 然后调用 to 方法...

你之前的方式...你是request上调用to然后然后 将结果传递给 expect... 即分组很重要 ;)

在原测试更改

api_constraints_v1.matches?(request).should be_true

expect(api_constraints_v1.matches?(request)).to be_truthy

expect(api_constraints_v1.matches?(request)).to be(true)

如果您希望只返回一个布尔值。

我在我的 rails-api-base 项目中使用了相同的 ApiConstraints,当您尝试 matches? 使用 non-default 版本而不指定 Accept 时它崩溃了] header.

我添加了以下测试(崩溃):

it 'returns false when not default and no Accept header' do
  request = double(host: 'api.marketplace.dev')
  expect(api_constraints_v1.matches?(request)).to be false
end

我修复了 ApiConstraints:

def matches?(req)
  @default ||
    (req.respond_to?('headers') &&
     req.headers.key?('Accept') &&
     req.headers['Accept'].include?("application/vnd.marketplace.v#{@version}"))
end

希望对您有所帮助!