如何使用 factory_bot 来构建缺乏访问方法的对象?

huangapple go评论90阅读模式
英文:

How to use factory_bot to build objects that lack accessor methods?

问题

  1. class Person
  2. attr_reader :name # 但没有 attr_accessor
  3. def initialize(name)
  4. @name = name
  5. end
  6. end
  7. FactoryBot.define do
  8. factory :person do
  9. name { 'Grace' }
  10. end
  11. end

如何使用 factory_bot 创建一个 Person?如果尝试 build :person,会出现以下错误:

  1. NoMethodError .. undefined method `name='

我编写了一个自定义构建策略,它可以工作,但我对它不满意,因为我不得不使用 instance_variable_get 来访问私有库对象。

  1. class BuildNew
  2. def association(runner)
  3. runner.run
  4. end
  5. # @param evaluation [FactoryBot::Evaluation]
  6. def result(evaluation)
  7. attributes = evaluation.hash
  8. model_class = evaluation.instance_variable_get(:@attribute_assigner).send(:build_class_instance).class
  9. model_class.new(attributes)
  10. end
  11. end
  12. FactoryBot.register_strategy(:build_new, BuildNew)
  1. <details>
  2. <summary>英文:</summary>
  3. Given a data model that lacks accessor methods,
  4. ```ruby
  5. class Person
  6. attr_reader :name # but NO attr_accessor
  7. def initialize(name)
  8. @name = name
  9. end
  10. end
  11. FactoryBot.define do
  12. factory :person do
  13. name { &#39;Grace&#39; }
  14. end
  15. end

How can I use factory_bot to build a Person? If we try build :person we get:

  1. NoMethodError .. undefined method `name=&#39;

I wrote a custom build strategy which works, but I am not pleased with it because I had to use instance_variable_get to access private library objects.

  1. class BuildNew
  2. def association(runner)
  3. runner.run
  4. end
  5. # @param evaluation [FactoryBot::Evaluation]
  6. def result(evaluation)
  7. attributes = evaluation.hash
  8. model_class = evaluation.instance_variable_get(:@attribute_assigner).send(:build_class_instance).class
  9. model_class.new(attributes)
  10. end
  11. end
  12. FactoryBot.register_strategy(:build_new, BuildNew)

答案1

得分: 2

以下是翻译好的部分:

似乎自定义构建策略是不必要的。可以使用 initialize_with 更简单地完成这个任务。

  1. FactoryBot.define do
  2. factory :person do
  3. initialize_with { new(attributes) }
  4. name { 'Grace' }
  5. end
  6. end
英文:

It seems the custom build strategy was unnecessary. This can be done much more simply using initialize_with.

  1. FactoryBot.define do
  2. factory :person do
  3. initialize_with { new(attributes) }
  4. name { &#39;Grace&#39; }
  5. end
  6. end

huangapple
  • 本文由 发表于 2023年6月15日 06:18:13
  • 转载请务必保留本文链接:https://go.coder-hub.com/76477924.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定