我的代码使用元编程并具有动态方法。我正试图找出在RSpec3中测试它们的最佳方法。下面是一个有待测试的例子:
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的实例
Placements::Status.create(system_name: "visible")我希望Placements::Status.visible方法会出现。由于动态方法依赖于数据库中的数据,所以我试图找出使用RSpec捕获数据的最佳方法
为了创建一个记录,然后再次加载一个模型文件,我在我的测试套件中使用了一个before挂钩:
before(:each) do
  create(:visible)
  load 'app/models/placements/status.rb'
end它可以工作,我可以调用Placements::Status.visible,但它看起来不太优雅(使用工厂)。是否有更好/正确的方法来重新加载类来查看在数据库中创建的记录?在钩或类似的东西之前还有其他的吗?
发布于 2022-04-01 21:13:49
这里的考古学家..。
有趣的用例。解决这种问题的方法可能是将安装代码移动到可以从测试中调用的方法中,而不是依赖于加载文件时调用它。然后,您可以在文件加载以供生产使用时执行该方法,但可以在测试中直接运行该方法以进行测试使用。看起来可能是这样的:
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然后,测试看起来可能是这样的:
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?:
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
endhttps://stackoverflow.com/questions/41038407
复制相似问题