首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在RSpec中测试动态类方法的适当方法

在RSpec中测试动态类方法的适当方法
EN

Stack Overflow用户
提问于 2016-12-08 11:29:45
回答 1查看 631关注 0票数 4

我的代码使用元编程并具有动态方法。我正试图找出在RSpec3中测试它们的最佳方法。下面是一个有待测试的例子:

代码语言:javascript
运行
复制
module Placements
  class Status < ActiveRecord::Base
    ...
    class << self
      Placements::Status.unscoped.pluck(:system_name).each do |system_name|
        define_method system_name do
          unscope(where: :archived).find_by_system_name(system_name)
        end
      end
    end
    ...
  end
end

使用类似于Placements::Status的实例

代码语言:javascript
运行
复制
Placements::Status.create(system_name: "visible")

我希望Placements::Status.visible方法会出现。由于动态方法依赖于数据库中的数据,所以我试图找出使用RSpec捕获数据的最佳方法

为了创建一个记录,然后再次加载一个模型文件,我在我的测试套件中使用了一个before挂钩:

代码语言:javascript
运行
复制
before(:each) do
  create(:visible)
  load 'app/models/placements/status.rb'
end

它可以工作,我可以调用Placements::Status.visible,但它看起来不太优雅(使用工厂)。是否有更好/正确的方法来重新加载类来查看在数据库中创建的记录?在钩或类似的东西之前还有其他的吗?

EN

回答 1

Stack Overflow用户

发布于 2022-04-01 21:13:49

这里的考古学家..。

有趣的用例。解决这种问题的方法可能是将安装代码移动到可以从测试中调用的方法中,而不是依赖于加载文件时调用它。然后,您可以在文件加载以供生产使用时执行该方法,但可以在测试中直接运行该方法以进行测试使用。看起来可能是这样的:

代码语言:javascript
运行
复制
module Placements
  class Status < ActiveRecord::Base
    ...
    class << self
      configure_data_driven_methods

      def configure_data_driven_methods
        Placements::Status.unscoped.pluck(:system_name).each do |system_name|
          define_method system_name do
            unscope(where: :archived).find_by_system_name(system_name)
          end
        end
      end
    end
    ...
  end
end

然后,测试看起来可能是这样的:

代码语言:javascript
运行
复制
RSpec.describe Placements::Status do
  it "has a visible method" do
    # arrange (setup the test)
    create(:visible)

    # act (do the thing)
    described_class.configure_data_driven_methods

    # assert (that the thing happened)
    expect(described_class.visible).not_to raise(NoMethodError)
  end
end

另一种选择是在method_missing的路径上,在启动时不实际创建方法,而是在调用缺少的方法时查询数据库,以查看是否应该存在该方法。这有一个缺点,就是在调用该方法时响应速度较慢。但是,它的优点是不需要重新启动就可以将方法添加到正在运行的应用程序中。而且,测试这种方法将是一个简单的问题,测试method_missing方法。

编辑

在考虑了这一点之后,我想我应该像这样使用respond_to?

代码语言:javascript
运行
复制
RSpec.describe Placements::Status do
  it "has a visible method" do
    # arrange (setup the test)
    create(:visible)

    # act (do the thing)
    described_class.configure_data_driven_methods

    # assert (that the thing happened)
    expect(described_class.respond_to?(:visible)).to be true
  end
end
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/41038407

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档