无法使用 rspec 测试控制器

Can't test controllers with rspec

我 运行在一个全新的 Rails 5 项目

中通过简单的 rspec 控制器测试遇到了一个大问题

这是我的 routes.rb

Rails.application.routes.draw do
  get '/foo', to: 'application#foo'
  get '/bar', to: 'application#foo'
end

这是我的 ApplicationController.rb

class ApplicationController < ActionController::Base
  def foo
    render html: 'foo', status: 200
  end

  def bar
    render html: 'bar', status: 200
  end
end

如果我使用 rails s 启动服务器,我可以访问 /foo/bar 端点并看到正确的 foo html 页面。

然而,当我 运行 这个 rspec:

ENV['RAILS_ENV'] = 'test'
require File.expand_path('../../config/environment', __dir__)
require 'rspec/rails'

RSpec.describe ApplicationController, type: :controller do  
  it 'can get foo' do
    get 'foo'
  end

  it 'can get bar' do
    get 'bar'
  end
end

测试失败,输出如下:

1) ApplicationController can get bar
 Failure/Error: get 'bar'

 ActionController::UrlGenerationError:
   No route matches {:action=>"bar", :controller=>"application"}

为什么 rspec 我的浏览器可以找到我的 /bar 路由?

奇怪的是,如果我在 routes.rb 文件中更改该路线以使用 bar 操作:

get '/bar', to: 'application#bar'

突然rspec可以找到路由,测试通过...

虽然我需要对我的路线使用任意操作,因此符合此模式以满足 rspec 不是一个选项。我怎样才能让 rspec 工作?

你试过这个路径(get '/bar', to: 'application#foo')可以在你的浏览器中访问吗?

将您的控制器规格更改为请求规格,这是从 RSpec 3.5

开始在 Rails 中测试控制器的首选方式

您收到该错误是因为在您的原始配置中您没有将 #bar 操作绑定到 URL。因此,当规范执行 #bar 时,该操作没有 URL。

控制器规格并不像您想象的那样工作;没有任何尝试请求您指定的路径。相反,它会执行您在 #bar 操作中编写的代码并从响应中提取 URL。

为了缓解这种情况,您可以将规格 type: 更改为 :request 而不是 :controller

那么你可以这样做:

RSpec.describe ApplicationController, type: :request do
  it 'can get foo' do
    get '/foo'
  end

  it 'can get bar' do
    get '/bar'
  end
end