简体   繁体   English

如何在rspec中存根HTTP POST请求?

[英]How to stub HTTP POST request in rspec?

I have a controller which contains a method and some conditional statements. 我有一个包含方法和一些条件语句的控制器。 the following is a sample of that controller. 以下是该控制器的示例。

class <controllername> < ApplicationController
def method
  if params["c"]
   http = Net::HTTP.new(uri.host, uri.port)
   req = Net::HTTP::Post.new("api_url_here")
   response = http.request(req)
   array = JSON.parse(response.body)
   url = params["s"]
   .....
  elsif params["e"]
   .....
  else
   .....
  end
end
end

I wrote rspec for the above controller 我为上述控制器编写了rspec

it "should do something" do
   array ="some array values"
   get :method, {"c" => "value for c", "s" => "value for s"}
   expect(response).to have_http_status(200)
end

I know the above rspec method is completely wrong. 我知道上面的rspec方法是完全错误的。 when this case runs the value for array and response are obtained by post call inside method and the response is HTTPBADREQUEST as expected. 当这种情况下运行时, arrayresponse的值是通过method内部的post调用获得的,并且responseHTTPBADREQUEST如预期的那样。

What I want is 我想要的是

To stub those values for array and response in the spec case(these values will be needed for later operations) and my spec case to not call HTTP::POST inside the method 在规范情况下将这些值存入数组和响应中(这些值将在以后的操作中使用),而我的规范情况下不要在method内调用HTTP :: POST

you can mock the answer 你可以嘲笑答案

expect_any_instance_of(Net::HTTP::Post).to receive(:request) { response_data_here }

You can also use VCR: https://github.com/vcr/vcr 您也可以使用VCR: https//github.com/vcr/vcr

When you run VCR for the first time, it will do the real request and save the response as a fixture, the second time it will use the fixture and avoid the real http request 第一次运行VCR时,它将执行实际请求并将响应保存为Fixture,第二次使用VCR并避免实际的http请求

VCR is pretty handy, but since it always runs the real request the first time it's not as flexible in allowing you to mock any response that you like. VCR非常方便,但是由于它总是在第一次运行真正的请求时,它在允许您模拟所需的任何响应时就没有那么灵活。

Try fakeweb , which lets you do just that. 尝试一下fakeweb ,它使您可以做到这一点。 You can mock all requests to your URL like: 您可以模拟对URL的所有请求,例如:

FakeWeb.register_uri(:get, "http://my-url.com", :body => "my mock response")

It doesn't seem to have been updated for over a year, but should still work for Rails 3 and 4. 它似乎没有更新一年多,但仍应适用于Rails 3和4。

You won't be able to cleanly mock out http, req, or response because they are local variables. 您将无法完全模拟出http,req或response,因为它们是局部变量。 Consider making them class or instance variables such that you can override them. 考虑使它们成为类或实例变量,以便您可以覆盖它们。

Better yet, use the right tool for the job. 更好的是,使用正确的工具完成工作。 I recommend using vcr tests so that you can mock out the entire HTTP stack. 我建议使用vcr测试,以便您可以模拟整个HTTP堆栈。 With VCR, you can record a request and play it back in your tests so you can get the exact mocked out data that you. 使用VCR,您可以记录一个请求并在测试中将其回放,以便获得确切的模拟数据。

https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/getting-started https://www.relishapp.com/vcr/vcr/v/2-9-3/docs/getting-started

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM