【问题标题】:Why am I getting a string/hash comparison failure?为什么会出现字符串/哈希比较失败?
【发布时间】:2019-12-05 15:02:45
【问题描述】:

我编写了一个发出 HTTP GET 请求的函数(截断和简化)。

# get_request.rb
require "http"

def get_request
  HTTP.get("<https://github.com>")
end

我已经为请求编写了一个测试。

require "request"

RSpec.describe "#get_request" do
  it "makes a successful GET request" do
    # GIVEN
    http_response = double("http", body: "Hello world!")

    # WHEN
    response = get_request

    # THEN
    expect(HTTP).to receive(:get).with("<https://github.com>").and_return(http_response)
    expect(response.body).to eq("Hello world!")
  end
end

但是,测试因比较失败而失败。

$ bundle exec rspec
F

Failures:

  1) #get_request makes a successful GET request
     Failure/Error: expect(response.body).to eq("Hello world!")

       expected: "Hello world!"
            got: #<HTTP::Response::Body:3fe63e519550 @streaming=false>

       (compared using ==)

       Diff:
       @@ -1,2 +1,2 @@
       -"Hello world!"
       +#<HTTP::Response::Body:3fe63e519550 @streaming=false>

     # ./spec/request_spec.rb:13:in `block (2 levels) in <top (required)>'

Finished in 0.32713 seconds (files took 0.25261 seconds to load)
1 example, 1 failure

Failed examples:

rspec ./spec/request_spec.rb:4 # #get_request makes a successful GET request

为什么response.body 等于&lt;HTTP::Response::Body:3fe63e519550 @streaming=false&gt; 哈希而不是我预期的"Hello world!" 字符串?如何让测试通过?

【问题讨论】:

    标签: ruby unit-testing rspec httprequest


    【解决方案1】:

    如果您想在测试的底部出现异常,则必须使用间谍模式。 https://relishapp.com/rspec/rspec-mocks/docs/basics/spies

    RSpec.describe "#get_request" do
      it "performs the request successfully" do
            http_response = double("http", body: "Hello world!")
            allow(HTTP).to receive(:get).and_return(http_response)
    
            response = get_request
    
            expect(HTTP).to have_received(:get).with("https://www.github.com")
            expect(response).to eq(http_response)
      end
    end
    

    【讨论】:

      【解决方案2】:

      测试替身需要在调用函数之前就位。¹要使测试通过,请将第一个期望移到 get_request 方法上方。

      例如:

      require "request"
      
      RSpec.describe "#get_request" do
        it "makes a successful GET request" do
          # GIVEN
          http_response = double("http", body: "Hello world!")
          expect(HTTP).to receive(:get).with("<https://github.com>").and_return(http_response)
      
          # WHEN
          response = get_request
      
          # THEN
          expect(response.body).to eq("Hello world!")
        end
      end
      

      ¹感谢 Jeremy Weathers 帮助回答问题的“为什么”部分。

      【讨论】:

      • Ryan,您正在将测试替身与期望结合起来,并且测试替身需要在示例的操作部分之前就位。您可能应该将这些解开:allow(HTTP).to receive(:get).with("&lt;https://github.com&gt;").and_return(http_response) 在 GIVEN 部分,expect(HTTP).to have_received(:get).with("&lt;https://github.com&gt;") 在 THEN 部分。
      • @JeremyWeathers “测试替身需要在行动之前到位”是关键。感谢您的回答!
      猜你喜欢
      • 1970-01-01
      • 2010-10-22
      • 1970-01-01
      • 1970-01-01
      • 2011-03-27
      • 2020-04-03
      • 2011-04-04
      • 2015-03-07
      • 2021-03-26
      相关资源
      最近更新 更多