【问题标题】:How to develop a Rails3 engine against a real app, using RSpec?如何使用 RSpec 针对真实应用开发 Rails3 引擎?
【发布时间】:2011-07-05 18:49:00
【问题描述】:
关于引擎开发和使用虚拟应用进行测试的文章很多。
在我们的例子中,我们正在开发一个引擎,它不是一个独立的实体,而是依赖于一个真实的 Rails 3 应用程序。我们仍然希望此代码存在于引擎中,而不是成为应用程序的一部分,因为引擎的工作是从具有自己的表和模型映射的遗留系统中导入数据,我们希望最终再次将其删除。
旧遗留表和新架构之间的数据映射很复杂,我们希望对引擎进行 TDD(使用 rspec)。
- 我关注了Jose Valim's book "Crafting Rails Appliations",并且正在使用enginex gem。
- 我已将
/spec/dummy_app 替换为指向真实 Rails 3 应用程序的 git 子模块。
- 我在从引擎加载模型时遇到问题(未定义的符号错误),因为真正的应用程序的 Gemfile 没有指向引擎,而且我也无法修改
config/application.rb 以要求引擎(其中如本书第 15-16 页所述)。
- 我将引擎的
lib 文件夹包含在spec_helper 中的加载路径$: 中,并且路径可用。
- 将
require 放入spec_helper.rb 并没有解决问题。
- 我想知道是否有一个内部 Rails API(或一个聪明的猴子补丁)可以挂接到真实应用程序的启动顺序并需要引擎,而无需修改真实应用程序的代码(因为它在子模块中) )。
- 另一个我不太确定的问题是我有 2 个 Gemfile(一个在引擎中,一个在应用程序中),当引擎处于活动状态时,它们都应该被使用。
想法?
【问题讨论】:
标签:
ruby-on-rails-3
rspec
rails-engines
【解决方案1】:
所以,我想出了一些事情,并会回答我自己的问题,现在我已经开始工作了。
为简单起见,我将我的 gem 的名称称为“my_gem”和“MyGem”:
在engine.rb 文件中,我添加了:
require 'my_gem'
require 'rails'
这修复了以下类型的错误:
my_gem/lib/my_gem/engine.rb:2: uninitialized constant MyGem::Rails (NameError)
在spec_helper.rb,我在顶部添加了:
require 'bundler/setup'
require 'my_gem'
这是为了确保立即初始化 Bundler,而不是通过应用程序初始化。这样我就可以在这里加载 MyGem,它会被挂接到应用程序的初始化序列中。这修复了引擎模型类的NameError 异常。
这就留下了Gemfile 使用什么的问题。问题是我的应用有自己的 gemfile,而 gem/engine 需要在自己的 Gemfile 中单独依赖。
我找不到任何用于 Bundler 的 API 将两个 Gemfile 传递给它,实际上 Bundler 似乎是围绕单个权威 Gemfile 的假设构建的。所以我在spec_helper 中生成了一个。我获取应用程序的 gemfile 并附加 gemspec,它以 GemSpec 格式指向 gem 的依赖项。 (顺便说一句,Jose Valim 的书中缺少关于 gemspec 的提示)。
我不知道是否有比在测试启动期间连接文件更好的方法。如果你知道,请回复。
有用的资源是: