【问题标题】:Rspec controller spec on namespaced controller finds the global controller with same name命名空间控制器上的 Rspec 控制器规范找到具有相同名称的全局控制器
【发布时间】:2016-07-19 02:36:26
【问题描述】:

在为命名空间控制器创建控制器规范时,当还有一个同名的全局控制器时,我遇到了一个奇怪的问题。

控制器名称为HomeControllerBackend::HomeController

注意我还没有创建文件app/controllers/backend/home_controller.rb,只有全局控制器存在app/controllers/home_controller.rb

因此,我希望测试会出现错误,但事实并非如此。它过去了,一切都是绿色和快乐的。

我的规格是这样的

#spec/controllers/backend/home_controller_spec.rb
require 'rails_helper'

RSpec.describe Backend::HomeController, type: :controller do
  before do
    user = FactoryGirl.create(:user)
    allow(controller).to receive(:authenticate_user!).and_return(true)
    allow(controller).to receive(:current_user).and_return(user)
  end
  describe "GET #index" do
    it "returns http success" do
      get :index
      expect(response).to have_http_status(:success)
    end
  end

end

但是,如果我将全局 HomeController 中的名称更改为其他名称,例如 NotMyHomeController,则测试失败并显示错误提示

Unable to autoload constant HomeController, expected app/controllers/home_controller.rb to define it

这让我怀疑 Rspec 不会打扰 Rspec.describe 函数中的“后端”部分。

是我做错了什么还是我错过了其他重要的部分?恕我直言,这个规范不应该通过(用甘道夫的话说)。

我正在使用 Rails 4.2.6,Rspec-Rails 3.4.2

更新

正如 Max 指出的,这可能不是 Rspec 问题,而是 Rails 自动加载的问题。

但是我试着只是打字

Backend::HomeController

在 Rails 控制台中,但出现了预期的错误

NameError: uninitialized constant Backend::HomeController

还有according to the Rails guide,控制台和测试套件都会自动加载。但是我认为我在这里走在正确的轨道上。

【问题讨论】:

  • 我猜它的 Rails 自动加载器在做一些奇怪的事情 - 它通过猴子补丁 Object.const_missing 工作,通常只会引发 NameError: uninitialized constant Backend::HomeController。它与 RSpec 关系不大。
  • 感谢您为我解决这个问题。您对如何进一步研究 Rails Autoloader 有什么建议吗?
  • 您可能想尝试看看如果将其定义为绝对而不是相对会发生什么:RSpec.describe ::Backend::HomeController
  • 感谢您的提示,不幸的是,使用绝对名称并没有帮助,如果我更改全局 HomeController 的名称,仍然会出现同样的问题和错误消息

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


【解决方案1】:

我之前也遇到过同样的问题 - 你可以在这里阅读整个问题:

Object.const_get and Rails - cutting off parent module names

但答案的核心来自用户 Apneadiving 的this 答案:

请注意,Rails 开发模式中存在恶性案例。为了获得速度,加载了严格的最小值。然后 Rails 在需要时查找类定义。

但这有时会失败的大例子,当你说::User已经加载,然后寻找::Admin::User。 Rails 不会寻找它,它会认为 ::User 可以解决问题。

这可以在您的代码中使用require_dependency 语句来解决。

【讨论】:

  • 谢谢!我最终在我的规范顶部添加了require_dependency "#{::Rails.root}/app/controllers/backend/home_controller,它解决了问题
猜你喜欢
  • 1970-01-01
  • 2015-03-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-05-18
  • 2019-07-20
  • 2017-03-08
相关资源
最近更新 更多