我正在尝试使用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,但老实说,此时我真的很不确定。任何和所有的意见都表示赞赏,我很高兴澄清我在这里提出的任何观点。非常感谢!
答案 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)
如果弹性搜索是问题所在,则可以尝试
# in your gemfile
group :test do
gem 'webmock'
end
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文档。