Rails和RSpec:在不同的命名空间(模块)中测试具有相同名称的控制器

我有使用RSpec 3.4.0测试的rails 4.1.16 API应用程序,我遇到了在不同模块中测试名为同名的类的问题。

结构是:

app/controllers/bar/notifications_controller.rb class Bar::NotificationsController < ApiController ... end 

和控制器在不同的模块中具有相同的名称:

 app/controllers/foo/bar/notifications_controller.rb module Foo class Bar::NotificationsController < ApiController ... end end 

Foo是一个新模块,还没有测试。 添加之后,旧的Bar::NotificationsController所有相应控制器测试都开始失败。

规范文件:

 spec/controllers/bar/notifications_controller_spec.rb require 'spec_helper' describe Bar::NotificationsController, type: :controller do ... end 

该规范文件中的所有测试都失败并出现相同的错误:

 RuntimeError: @controller is nil: make sure you set it in your test's setup method. 

当我更改Foo模块中的控制器名称时,问题不存在:

 app/controllers/foo/bar/foo_notifications_controller.rb module Foo class Bar::FooNotificationsController < ApiController ... end end 

我已经尝试在spec文件的顶部添加require’bar require 'bar/notifications_controller'并使用类名作为字符串describe "Bar::NotificationsController, type: :controller但它没有解决问题(同样的错误)。

为什么会这样? 解决办法是什么?

我想相信有一件小事我还没试过,我不需要污染我的代码和结构与无意义的名称只是为了使规范通过。

非常感谢您的帮助!

通常,我会在类定义中包含所有命名空间。 就像是:

 app/controllers/foo/bar/notifications_controller.rb class Foo::Bar::NotificationsController < ApiController ... end 

乍一看,这看起来可能与以下内容相同:

 app/controllers/foo/bar/notifications_controller.rb module Foo class Bar::NotificationsController < ApiController ... end end 

事实上,这些是不同的。 不同之处在于Rails如何处理常量的自动加载。 我不会在这里详细介绍,因为它是一个较长的主题,并且在web-o-sphere中有很好的文章/post。

你可以找到关于Rails如何像这样处理自动加载的好文章(或尝试使用Googling rails constant loading

此外,正如文章所述,Ruby常量加载的操作与Rails加载不同。 关于Ruby常量加载的好信息可以在这里找到(或尝试使用Googling ruby constant loading )。