【发布时间】:2021-08-31 18:42:18
【问题描述】:
我有以下导轨控制器
class FoodsController < ApplicationController
before_action :set_food, only: [:show, :update, :destroy]
# GET /foods/1
def show
#render json: @food
render json:
{
"barcode": @food.barcode,
"product": @food.product
}
end
private
# Use callbacks to share common setup or constraints between actions.
def set_food
#@food = Food.find(params[:id])
code = params[:id]
product = Openfoodfacts::Product.get(code, locale: 'fr')
@food = Food.create_with(product: product.product_name).find_or_create_by(barcode: code)
end
# Only allow a list of trusted parameters through.
def food_params
params.require(:food).permit(:barcode, :product)
end
end
我有以下 rspec 测试
require 'rails_helper'
RSpec.describe FoodsController, type: :request do
include_context 'openfood_context'
let(:headers) { { Authorization: "Token #{TokenAuth::API_TOKEN}" } }
let(:response_body) { JSON.parse(response.body) }
let(:given_product) { response_body['product'] }
let(:given_barcode) { response_body['barcode'] }
before do
get food_path(id: barcode), headers: headers
expect(response).to have_http_status(:ok)
end
it 'returns the product name' do
expect(given_product).to eq product
end
it 'returns the barcode' do
expect(given_barcode).to eq barcode
end
end
页面有效,当我点击 foods/099482476885 路线时,我得到这张图片中的输出enter image description here。但是当我运行规范时,我得到下面的错误
1) FoodsController returns the product name
Failure/Error: product = Openfoodfacts::Product.get(code, locale: 'fr')
WebMock::NetConnectNotAllowedError:
Real HTTP connections are disabled. Unregistered request: GET https://fr.openfoodfacts.org/api/v0/produit/049000061017.json with headers {'Accept'=>'*/*', 'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3', 'User-Agent'=>'Ruby'}
You can stub this request with the following snippet:
stub_request(:get, "https://fr.openfoodfacts.org/api/v0/produit/049000061017.json").
with(
headers: {
'Accept'=>'*/*',
'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
'User-Agent'=>'Ruby'
}).
to_return(status: 200, body: "", headers: {})
============================================================
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/net_http.rb:114:in `request'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/net_http.rb:123:in `start_without_connect'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/webmock-3.13.0/lib/webmock/http_lib_adapters/net_http.rb:150:in `start'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/openfoodfacts-0.6.0/lib/openfoodfacts/product.rb:25:in `get'
# ./app/controllers/foods_controller.rb:23:in `set_food'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/rack-2.2.3/lib/rack/etag.rb:27:in `call'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/rack-2.2.3/lib/rack/conditional_get.rb:27:in `call'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/rack-2.2.3/lib/rack/head.rb:12:in `call'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/railties-6.1.3.2/lib/rails/rack/logger.rb:37:in `call_app'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/railties-6.1.3.2/lib/rails/rack/logger.rb:26:in `block in call'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/railties-6.1.3.2/lib/rails/rack/logger.rb:26:in `call'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/rack-2.2.3/lib/rack/runtime.rb:22:in `call'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/rack-2.2.3/lib/rack/sendfile.rb:110:in `call'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/railties-6.1.3.2/lib/rails/engine.rb:539:in `call'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/rack-test-1.1.0/lib/rack/mock_session.rb:29:in `request'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/rack-test-1.1.0/lib/rack/test.rb:266:in `process_request'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/rack-test-1.1.0/lib/rack/test.rb:119:in `request'
# ./spec/requests/foods_controller_spec.rb:13:in `block (2 levels) in <top (required)>'
# /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/webmock-3.13.0/lib/webmock/rspec.rb:37:in `block (2 levels) in <top (required)>'
然后我尝试将以下存根添加到 spec/spec_helper.rb,但收到与图片中类似的错误。我该如何解决这个规范问题?
config.before(:each) do
stub_request(:get, /api.openfoodfacts.org/).
with(headers: {
'Accept'=>'*/*',
'Accept-Encoding'=>'gzip;q=1.0,deflate;q=0.6,identity;q=0.3',
'User-Agent'=>'Ruby'}).
to_return(status: 200, body: "stubbed response", headers: {})
end
【问题讨论】:
-
一个明显的问题是您的存根正则表达式中的主机是
api.openfoodfacts.org,但在错误消息中,GET 似乎命中fr.openfoodfacts.org,因此您的存根不匹配。如果您仍然有问题,请尝试从存根中删除标头,以确保首先一切正常。 -
另外,请不要发布错误/堆栈跟踪的屏幕截图。只需将(相关)文本复制到您的问题中即可。如果错误文本不是单独的图像,那么发现问题会容易 10 倍。
-
当我将 sub 中的主机从 api.openfoodfacts.org 更改为 fr.openfoodfacts.org 我得到 ``` FoodsController 返回产品名称失败/错误:product = Openfoodfacts::Product.get (代码,语言环境:'fr') JSON::ParserError: 767: unexpected token at '' # /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/openfoodfacts-0.6.0/lib/openfoodfacts/ product.rb:26:in
get' # ./app/controllers/foods_controller.rb:23:inset_food' # /home/ubuntu/.rvm/gems/ruby-2.6.3/gems/rack-2.2.3/lib/rack/etag.rb:27:in `` ` -
您收到 JSON 解析错误,所以我认为您的原始问题已解决,问题可能是您的存根返回的 JSON(“存根正文”?)导致您的
Openfoodfacts东西消化不良。如果您确保存根是一个有效的示例响应,它可能会变得更好。 -
服务有可能被调用两次。可能你需要模拟两个 enpoint。注意当你模拟一个时会发生什么变化。 (也许 api.foodfacts 会返回 301 重定向到 fr.foodfacts?)
标签: ruby-on-rails ruby api rspec rspec-rails