ruby-on-rails 使用Rails和RSpec自动加载类后重新示例化类

hjqgdpho  于 2023-01-27  发布在  Ruby
关注(0)|答案(1)|浏览(209)

我有这样一个类,我在其中创建了一些依赖于数据库表的属性:

class Form
 include ActiveAttr::Model

 attribute :type, type: String
 attribute :default_name, type: String

 Languages.all.each do |lang|
  attribute :"name_#{lang}", type: String
 end
end

这很好用,但是我用RSpec做了两个测试:
单元测试:

require 'rails_helper'

RSpec.describe Form, type: :class do
  ...
end

E2E测试:

require 'rails_helper'

RSpec.describe 'forms', type: :system do
  let!(:languages) do
    create(:language, name: 'es')
    create(:language, name: 'en')
  end

  scenario 'accessing the page where I can see all the attributes of the Form' do
    @form = create(:form, :with_languages)
    visit form_page(@form)
  end

  ...

当我运行rspec时,Rails自动加载所有内容,并且创建Form类时数据库中还没有任何Language,因此它没有任何name_属性。第一个测试工作正常,但第二个测试失败,因为加载Form类时没有模拟的Language:

undefined method `name_en' for #<Form:0x000000014766c4f0>

这是因为为了加载视图,我们在控制器中执行了@view = Form.new(@form),显然它没有创建一个新对象。
如果我只运行第二个测试,它的工作就像一个魅力,我尝试与DatabaseCleaner,但它是相同的。
有没有办法做到这一点,而不禁用自动加载?我试图禁用它与config.autoload_paths,但它给我成千上万的错误,这是一个巨大的应用程序。
我尝试了几个解决方案,但没有一个工作,我需要的是重新创建该类。

6rqinv9w

6rqinv9w1#

@view = Form.new(@form)确实创建了一个新对象,但它没有重新加载类,因此属性不会再次定义。attribute是一个类方法,它在加载Form类时运行,在调用Form.new时不运行。
我不知道你用Form类做什么,通常你会为每个表单都有一个特定的类。你可以稍后添加属性,但这是对Form类的永久性更改:

>> Form
# Form class is autoloaded and all attributes are defined
 Language Load (0.9ms)  SELECT "languages".* FROM "languages"
=> Form(default_name: String, type: String)

>> Language.create(name: :en)
>> Form
# will not add language attributes
=> Form(default_name: String, type: String)

>> Form.attribute :name_en, type: String
=> attribute :name_en, :type => String
>> Form
=> Form(default_name: String, name_en: String, type: String)

初始化新对象时,可以更改Form类:
x一个一个一个一个x一个一个二个x
如果希望实际的类是动态的,那么类定义必须是动态的:
一个三个三个一个

相关问题