在不加载 ActiveRecord 的情况下测试 Rails 模块 [英] Testing Rails module without loading ActiveRecord

查看:46
本文介绍了在不加载 ActiveRecord 的情况下测试 Rails 模块的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发一个正在使用 RSpec 进行测试的 Rails 应用程序.经过大量等待测试完成后,我遵循了 Gary Bernhardt 的建议Paul Annesley 撰写的这篇内容丰富的帖子 并设置了一个分层的 spec_helper,我只加载我绝对需要的 Rails 部分,以缩短测试时间,并将功能提取到我单独测试的单独模块中.>

这在一定程度上起作用了.问题是我有一个模块(扩展 ActiveSupport::Concern),其中包含基于 ActiveRecord 功能的实例和类方法,例如结合动态查找器,如 find_and_create_by_.到目前为止,我已经能够创建一个包含模块的虚拟类并对其进行测试,但现在我想将更多逻辑从我的 ActiveRecord 模型移动到模块中.

具体的例子是回调、验证器和方法委托之类的东西,所有这些都与我正在访问的 API 相关.

尽管在我的测试中有两个选择,但我现在陷入困境:

  1. 存根和/或模拟我在模块中调用的每个 ActiveRecord 方法,这可以使测试保持快速,但可能会使测试代码变得非常复杂,或者
  2. 在测试中需要 activerecord,让我的虚拟类继承自 ActiveRecord::Base 并像测试任何其他 rails 模型一样测试模块,这会更慢但保持测试代码干净.

后一个选项并不真正吸引我,因为我在模块中隔离代码的全部原因是我想将它与 Rails 分开.我不是在这里寻找非黑即白的答案,但是有人对这种情况的最佳实践有任何建议或指示吗?非常感谢提前!

解决方案

选项 1 看起来很诱人,但恕我直言,它充满了危险.你需要做的嘲笑和存根的范围很像拉姆斯菲尔德的谚语之一 "unknown unknowns".您最终会删除所有 ActiveRecord 吗?

即使你可以让它工作,它是否能容忍 ActiveRecord 未来的变化?您是否需要更新您的模拟/存根以跟上新版本?

我很想看到一个可以为此目的替代 ActiveModel/ActiveRecord 的模拟库.不过我想说的是,除非你能容忍花费大量时间来构建这样的东西,否则你最好选择选项 2.

I'm working on a Rails app which I am testing with RSpec. After a lot of waiting for tests to finish, I've followed Gary Bernhardt's advice and this informative post by Paul Annesley and setup a tiered spec_helper where I only load what parts of Rails I absolutely need, to keep test times down, and extract functionality into separate modules which I test in isolation.

This is working up to a point. The problem is that I have a module (extending ActiveSupport::Concern) with instance and class methods that build on ActiveRecord functionality, e.g. tying in to dynamic finders like find_and_create_by_. So far I've been able to just create a dummy class which includes the module and test on that, but now I'd like to move more logic from my ActiveRecord model into the module.

Concrete examples would be stuff like callbacks, validators, and method delegation, all of which are related by the fact that they relate to an API I'm accessing.

I'm stuck now though with two choices in my tests:

  1. stub and/or mock every ActiveRecord method that I call in the module, which would keep the tests fast but potentially make the test code very complex, or
  2. require activerecord in the test, make my dummy class inherit from ActiveRecord::Base and just test the module as I would test any other rails model, which would be slower but keep the test code clean.

The latter option doesn't really appeal to me, since the whole reason I'm isolating the code in a module is that I want to separate it from Rails. I'm not looking for a black or white answer here, but would anyone have any advice or pointers to best practices on this situation? Thanks very much in advance!

解决方案

Option 1 seems tantalizing, but is fraught with peril IMHO. The scope of the mocking and stubbing that you would need to do is much like one of Rumsfeld's proverbial "unknown unknowns". Would you eventually end up stubbing out all of ActiveRecord?

Even if you could make it it work, would it tolerate future changes in ActiveRecord? Would you have to update your mocks/stubs to keep up with new versions?

I would love to see a mocking library that can substitute ActiveModel/ActiveRecord for this very purpose. I'd say though that unless you have tolerance for spending what could end up being a lot of time building such a thing, that you're better off going with option 2.

这篇关于在不加载 ActiveRecord 的情况下测试 Rails 模块的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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