Rails and RSpec: 在不同命名空间(模块)中测试具有相同名称的控制器
Rails and RSpec: Testing controllers with the same name in different namespace (module)
我有 rails 4.1.16 API 应用程序使用 RSpec 3.4.0 进行测试,我在测试 class 同名的应用程序时遇到问题在不同的模块中。
结构是:
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
我已经尝试在规范文件 require 'bar/notifications_controller'
之上添加并使用 class 名称作为字符串 describe "Bar::NotificationsController, type: :controller
但它没有解决问题(同样的错误)。
为什么会这样?解决方法是什么?
我想相信有一件我还没有尝试过的小事,我不必为了使规范通过而用无意义的名称污染我的代码和结构。
非常感谢您的帮助!
一般来说,我会在 class 定义中包含 all 命名空间。类似于:
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 如何处理常量的自动加载。我不会在这里详细介绍,因为这是一个较长的话题,而且网络领域中有很好的 articles/posts。
您可以找到有关 Rails 如何处理自动加载的好文章,例如 this one(或尝试使用谷歌搜索 rails constant loading
)
此外,正如文章所述,Ruby 常量加载与 Rails 加载的操作方式不同。可以找到关于 Ruby 常量加载的有用信息 here(或尝试谷歌搜索 ruby constant loading
)。
我有 rails 4.1.16 API 应用程序使用 RSpec 3.4.0 进行测试,我在测试 class 同名的应用程序时遇到问题在不同的模块中。
结构是:
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
我已经尝试在规范文件 require 'bar/notifications_controller'
之上添加并使用 class 名称作为字符串 describe "Bar::NotificationsController, type: :controller
但它没有解决问题(同样的错误)。
为什么会这样?解决方法是什么?
我想相信有一件我还没有尝试过的小事,我不必为了使规范通过而用无意义的名称污染我的代码和结构。
非常感谢您的帮助!
一般来说,我会在 class 定义中包含 all 命名空间。类似于:
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 如何处理常量的自动加载。我不会在这里详细介绍,因为这是一个较长的话题,而且网络领域中有很好的 articles/posts。
您可以找到有关 Rails 如何处理自动加载的好文章,例如 this one(或尝试使用谷歌搜索 rails constant loading
)
此外,正如文章所述,Ruby 常量加载与 Rails 加载的操作方式不同。可以找到关于 Ruby 常量加载的有用信息 here(或尝试谷歌搜索 ruby constant loading
)。