【问题标题】:How to test if an ActiveRecord association is being used with RSpec?如何测试 ActiveRecord 关联是否与 RSpec 一起使用?
【发布时间】:2018-08-22 16:40:26
【问题描述】:

查看他们的 Active Record 关联是否不再被使用的最佳方法是什么?如何编写 rspec 测试来查看关联是否不再被使用?

我必须重构其他人(不再是项目的一部分)的 Rails 模型。目前,我正在使用 atom 来查看是否在存储库中的其他地方调用了关联,但我知道这不是最好的方法。我想为模型构建单元测试,但不完全确定如何处理关联。目前,我正在使用 shoulda 匹配器和 factory_girl_rails。

【问题讨论】:

  • 在像 Ruby 这样的动态类型语言中,很难实现您想要做的事情 - 找到正在使用特定方法/关联的所有位置。我不确定这里是否有任何值得信赖的解决方案。见stackoverflow.com/a/9788511/3507206

标签: ruby-on-rails activerecord rspec


【解决方案1】:

至少有两种使用关联的方式:

  1. 显式地调用一个对象。

    object.association_name
    

    在这种情况下很容易跟踪:

    expect_any_instance_of(Model).to_not receive(:association_name)
    

    另一个问题是在您的测试结构中放置这种期望的位置。

  2. 隐式 - 在复杂查询或关联数据预加载中。

    Model.all.joins(:association_name)
    Model.all.includes(:association_name)
    

    在这种情况下,很难跟踪。

我建议另一种方法:

不要跟踪关联使用情况,而是在删除关联时检查测试是否通过。您可以安全地删除测试环境的关联。

例如,你可以替换这个:

has_many :association_name

用这个:

unless Rails.env.test?
  has_many :association_name
end

这不会破坏任何东西,并且只会在运行测试时引发错误,并且只有在某处使用关联时才会引发错误。

【讨论】:

  • 我不确定我是否理解。仅对测试禁用它有什么帮助?是的——当有人试图在规范中使用它时,你会得到“通知”。但是您仍然不知道它是否在生产代码中使用。它可以用于一些未涵盖的部分,因此规格在这里真的没有用......或者我在这里遗漏了一些东西。
  • 我认为这个想法是查看在运行规范时是否正在使用关联。否则@meta 的回答对我来说似乎相当不错。
  • 啊!然后我得到你的答案。无法说出真正的 OP 想的是哪一个……
  • 感谢您的建议。我正在查看这些关联是否正在生产中使用。我已尝试使用您的建议,即使用 expect_any_instance_of(Model).to_not receive(:association_name) 查找显式调用。您能否详细说明这是如何工作的?
  • 这仅在您运行规范时有效。阅读此文档:relishapp.com/rspec/rspec-mocks/v/2-14/docs/…!
【解决方案2】:

Rspec 为此目的使用reflect_on_association。一个例子是

it 'has many associations' do
    assc = Model.reflect_on_association(:other_model)
    expect(assc.macro).to eq :has_many
end

【讨论】:

  • 这只是测试关联是否存在。问题是关于测试关联是否真的在代码库中的任何地方使用。
  • 为什么不是更简单的is_expected.to have_many(:other_models)
  • 这根本不是问题的答案。 OP 询问如何检查关联是否未使用,而不是如何测试它是否已定义。
【解决方案3】:

我认为这是与软件设计本身一样古老的问题。

如何检查某些东西是否不再使用?

这是 ruby​​ 等动态语言中的一个问题。解决这个问题的方法很少。

1。使用端到端测试覆盖您的所有应用

通常情况下,很难达到 100% 的覆盖率,而且您可能无法轻松获得此解决方案

2。删除用法,看看是否一切正常

与第 1 点类似,但需要手动操作。在更大的系统中非常困难,而且通常您不会记录所有功能。

3。 Monkeypatch 和日志用法

对于关联,这可能是这样的:

has_namy :foos

def foos
  log 'foos is used!'
  super
end

但正如@chumakoff 在这里所说的https://stackoverflow.com/a/51982936/299774 该关联可能会在更多地方使用。因此,您需要进行一些调查以找到所有挂接您的登录的位置。

此解决方案也有一个缺点:您应该等待多长时间才能声明关联未使用?还要等半年吗?如果这么长时间没人使用它,但有一个功能一年使用一次,然后就坏了怎么办?

那么,我该怎么办?

这取决于应用程序的大小和重要性等。有时您可以冒险,有时您决定使用一些未使用的代码。或者您可以像这里Find unused code in a Rails app 一样获得更多创意。

或者,您可以为一小部分用户禁用此关联,并注意在您汇总日志/异常的任何位置出现异常。

如果数据库中有任何内容,也许您应该检查数据库?如果没有 - 你能找到一个从那里删除所有东西的迁移吗?可以联系作者吗?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多