Rails 和 RSpec:在不同的命名空间(模块)中测试具有相同名称的控制器 [英] Rails and RSpec: Testing controllers with the same name in different namespace (module)

查看:51
本文介绍了Rails 和 RSpec:在不同的命名空间(模块)中测试具有相同名称的控制器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have rails 4.1.16 API application that is tested using RSpec 3.4.0, and I experience problems with testing classes called the same name in a different module.

结构为:

app/controllers/bar/notifications_controller.rb

class Bar::NotificationsController < ApiController
  ...
end

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

and controller with the same name in a different module:

app/controllers/foo/bar/notifications_controller.rb

module Foo
  class Bar::NotificationsController < ApiController
    ...
  end
end

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

The Foo is a new module and does not have tests yet. After adding it, all the corresponding controller tests for the old Bar::NotificationsController started to fail.

规范文件:

spec/controllers/bar/notifications_controller_spec.rb

require 'spec_helper'

describe Bar::NotificationsController, type: :controller do
  ...
end

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

All the tests in that spec file fail with the same error:

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

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

The problem does not exist when I change the controller name in the Foo module:

app/controllers/foo/bar/foo_notifications_controller.rb

module Foo
  class Bar::FooNotificationsController < ApiController
    ...
  end
end

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

I already tried adding on top of the spec file require 'bar/notifications_controller' and using the class name as a string describe "Bar::NotificationsController, type: :controller but it did not solve the issue (the same error).

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

Why is this happening? What is the solution?

我想相信有一件小事我还没有尝试过,我不必为了让规范通过而用无意义的名称污染我的代码和结构.

I want to believe there is a tiny thing I did not try yet and I don't have to pollute my code and the structure with nonsense names just to make the specs pass.

非常感谢您的帮助!

推荐答案

一般来说,我会在类定义中包含 all 命名空间.类似的东西:

In general, I've take to including all namespacing in the class definition. Something like:

app/controllers/foo/bar/notifications_controller.rb

class Foo::Bar::NotificationsController < ApiController
  ...
end

虽然乍一看,这可能与以下内容相同:

While, at first glance, this might look the same as:

app/controllers/foo/bar/notifications_controller.rb

module Foo
  class Bar::NotificationsController < ApiController
    ...
  end
end

事实上,这些是不同的.不同之处在于 Rails 如何处理常量的自动加载.我不会在这里详细介绍,因为这是一个较长的主题,而且网络领域中有很多不错的文章/帖子.

These are, in fact, different. The difference is in how Rails handles autoloading of constants. I won't go into the details here because it's a longer topic and there are good articles/posts out in the web-o-sphere.

您可以找到关于 Rails 如何处理自动加载的好文章,例如 this一个(或尝试谷歌搜索rails 常量加载)

You can find good articles on how Rails handles autoloading like this one (or try Googling rails constant loading)

此外,如文章所述,Ruby 常量加载的操作方式与 Rails 加载不同.可以在此处找到有关 Ruby 常量加载的好信息(或尝试谷歌搜索 ruby constant loading).

Also, as the article notes, Ruby constant loading operates differently than Rails loading. Good information on Ruby constant loading can be found here (or try Googling ruby constant loading).

这篇关于Rails 和 RSpec:在不同的命名空间(模块)中测试具有相同名称的控制器的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆