将旧的Rspec语法转换为新语法

时间:2016-04-04 06:56:39

标签: ruby-on-rails rspec rails-api ruby-on-rails-5

我正在使用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,这些是我相关宝石的版本:

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)

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

3 个答案:

答案 0 :(得分:4)

在原始测试更改中

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)

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

答案 1 :(得分:1)

变化

expect request.to eq(api_constraints_v1)

expect(request).to eq(api_constraints_v1)

和其他规格中的问题相同......

expect是一种方法,你可以给出期望的东西(即request)......

request方法获得结果后,您就可以在其上调用to ...

之前的方式......你首先to上调用request然后然后将结果传递给{ {1}} ...即分组事项;)

答案 2 :(得分:0)

我在rails-api-base项目中使用了相同的ApiConstraints,当您使用非默认版本尝试matches?而未指定Accept标题时,它会崩溃

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

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

希望它有所帮助!