使用WebMock进行存根不拦截请求

时间:2016-10-05 11:40:20

标签: ruby-on-rails reactjs rspec-rails

我正在尝试使用WebMock将请求存根到Controller。但是,当我创建存根时,请求不会按照我期望或希望的方式被截获。

Controller除了根据查询参数呈现JSON之外什么都不做:

def index      
  render json: MyThing.search(params[:query]).as_json(only: [:id], methods: [:name_with_path])
end

存根如下:

mything_val = { ...json values... }
stub_request(:any, mything_path).with(query: { "query" => "a+thing" }).to_return(body: mything_val, status: 200)
page.find('.MyThingInput > input').set('a thing')

# Note: I've tried this with and without the `query:` parameter, as well as 
with and without specifying header info.

这是触发React组件。它的作用是,当一个或多个单词输入到输入中时,它会向输入的值发送一个带有输入值的mything_path的AJAX请求,该输出值作为JSON返回几个关于用户可能含义的建议。它们位于li内的.MyThingInput-wrapper元素中。

在spec文件中,我包括:

require 'support/feature_helper'
require 'support/feature_matchers'
require 'webmock/rspec'
WebMock.disable_net_connect!

当我将文本输入React组件时实际发生的情况是,无论WebMock存根是什么,它都会触及Controller,发出数据库请求,并且由于测试环境的某些限制而失败。我对这应该如何工作的理解是,当向mything_url发出请求时,它应该被WebMock截获,它将返回我预先定义的值,并且根本不会触及Controller。

我的猜测是,我在某种程度上嘲笑错误的URI,但老实说,此时我真的很不确定。任何和所有的意见都表示赞赏,我很高兴澄清我在这里提出的任何观点。非常感谢!

2 个答案:

答案 0 :(得分:1)

最终解决我的问题的原因是抄袭了模型。我试过捏住控制器,但遇到了问题;但是,这段代码可以解决问题:

before do
  mything_value = [{ "id" => "fb6135d12-e5d7-4e3r-b1h6-9bhirz48616", "name_with_path" => "New York|USA" }]
  allow(MyThing).to receive(:search).and_return(mything_value.to_json)
end

这样,它仍然会命中控制器,但会截断数据库查询,这是真正的问题,因为它使用了Elasticsearch(未在测试模式下运行。)

我对这样的JSON硬编码并不是非常高兴,但是我尝试了其他一些方法却没有成功。老实说,在这一点上,我只是考虑一下有效的方法。

有趣的是,我在Infused的建议之前尝试过这种方法,但无法正确理解语法;同样扼杀了控制器的行动。上床睡觉,醒来,用我认为的语法再次尝试是相同的语法,并且它有效。我只是慢慢地退后一步,感谢代码众神。

答案 1 :(得分:0)

如果弹性搜索是问题所在,则可以尝试

  • 安装Webmock
# in your gemfile
group :test do
gem 'webmock'
end
  • 取消对Elasticsearch的请求并返回JSON

spec_helper中类似的东西:

  config.before(:each) do
    WebMock.enable!
    WebMock.stub_request(:get, /#{ELASTICSEARCH_URL}/).to_return(body: File.read('spec/fixtures/elasticsearch/search-res.json'))ELASTICSEARCH_URL
    # and presumably, if you are using elasticsearch-rails, you'd want to stub out the updating as well:
    WebMock.stub_request(:post, /#{ELASTICSEARCH_URL}/).to_return(status: "200")
    WebMock.stub_request(:put, /#{ELASTICSEARCH_URL}/).to_return(status: "200")
    WebMock.stub_request(:delete, /#{ELASTICSEARCH_URL}/).to_return(status: "200")
  end

当然,这会取消对弹性搜索的所有调用,并为所有答案返回相同的JSON。如果每个查询需要不同的响应,请查阅webmock文档。