我正在尝试将旧ActionDispatch::IntegrationTest
测试移植到rspec。
该测试当前通过:
require 'test_helper'
class HeartbeatControllerTest < ActionDispatch::IntegrationTest
test "heartbeat" do
get "/heartbeat"
assert_response :success
end
end
我有一个HeartbeatController
返回200的:
class HeartbeatController < ApplicationController
def show
render(json: { 'status': 'ok' })
end
end
与配合使用效果很好curl
。
rake routes
显示路线:
Prefix Verb URI Pattern Controller#Action
heartbeat GET /heartbeat(.:format) heartbeat#show
我的测试非常简单:
require 'rails_helper'
describe HeartbeatController do
it 'succeeds' do
get '/heartbeat'
expect(response).to be_success
end
end
但是当我运行它时
Failures:
1) HeartbeatController succeeds
Failure/Error: get '/heartbeat'
ActionController::UrlGenerationError:
No route matches {:action=>"/heartbeat", :controller=>"heartbeat"}
# ./spec/controllers/heartbeat_controller_spec.rb:5:in `block (2 levels) in <top (required)>'
Finished in 0.00718 seconds (files took 1.11 seconds to load)
1 example, 1 failure
Failed examples:
rspec ./spec/controllers/heartbeat_controller_spec.rb:4 # HeartbeatController succeeds
如果这是一个控制器规范,则您要传递方法的名称而不是路由。
require 'rails_helper'
describe HeartbeatController do
it 'succeeds' do
get :show
expect(response).to be_success
end
end
控制器规范实际上并没有驱动整个Rails堆栈,它们只是创建了一个模拟请求,并将其传递给控制器实例,然后在控制器上调用方法。
出现路由错误的原因是ActionController::TestCase::Behavior
试图验证给定控制器/方法名称组合的路由是否存在。这样No route matches {:action=>"/heartbeat", :controller=>"heartbeat"}
。
众所周知,单元测试控制器的整个过程存在很大缺陷,因为您要嘲笑框架的大部分内容,而不是实际测试控制器的功能-它们响应HTTP请求。由于模拟了路由层和中间件堆栈,因此您的测试不会像真正的集成测试那样覆盖它们。
无论是导轨和RSpec团队劝阻直接测试控制器。而是使用实际驱动整个堆栈的请求规范。
# spec/requests/heartbeats_spec.rb
require 'rails_helper'
describe 'Heartbeats', type: :request do
describe "GET /heartbeats" do
it 'succeeds' do
get '/heartbeat'
expect(response).to be_successful
end
end
end
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句