Ruby on rails 使用Rspec和FactoryBot进行Rails测试

Ruby on rails 使用Rspec和FactoryBot进行Rails测试,ruby-on-rails,rspec,factory-bot,Ruby On Rails,Rspec,Factory Bot,我是rails rspec测试的新手,目前我需要创建嵌套数据结构并使用factorybot进行数据处理。当它用于控制器测试时。它不允许我做简单的Factorybot.create:model。 我找了很多。但似乎没有找到或理解解决方案。 因此,我需要创建的数据结构如下: "email":"", "name":"", "personalDetail":{ "height":"", "weight":"", "color":"" } "address":{ "street":"", "postal_

我是rails rspec测试的新手,目前我需要创建嵌套数据结构并使用factorybot进行数据处理。当它用于控制器测试时。它不允许我做简单的Factorybot.create:model。 我找了很多。但似乎没有找到或理解解决方案。 因此,我需要创建的数据结构如下:

"email":"",
"name":"",
"personalDetail":{
"height":"",
"weight":"",
"color":""
}
"address":{
"street":"",
"postal_code":""
},
"experience":""
}
**注意。这与关联无关,控制器中的数据是以这种方式接收的。没有关系 而我目前正在使用

initialize_with{{
"email":"",
"name":"",
"personalDetail":{
"height":"",
"weight":"",
"color":""
}
"address":{
"street":"",
"postal_code":""
},
"experience":""
}}
它适用于控制器测试,但在测试时无法更改键值,如:

FactoryBot.create(:model, name:"xyz")
,并且不适用于FactoryBot.create:model,这给了我错误

**Api::V1::someController获取索引 失败/错误:FactoryBot。创建:模型

 NoMethodError:
   undefined method `save!' for #<Hash:0x0000563db7324060>
 # ./spec/controllers/api/v1/somecontroller_spec.rb:11:in `block (2 levels) in <main>'
 # -e:1:in `<main>' **
这样我就可以使用它了。

工厂:job\u应用程序会猜测您想要创建类JobApplication的对象。要生成散列,需要将其显式化。看

由于Hash.new不接受一组键/值对,因此需要覆盖默认的初始化行为。我发现最简单的方法就是返回工厂的属性。看

那些使用符号键,你需要字符串键,所以我们使用。这还负责克隆属性,以防万一

factory :job_application, class: Hash do
  initialize_with do
    attributes.deep_stringify_keys
  end
end
现在,您可以按常规方式添加属性

factory :job_application, class: Hash do
  email { "jorb@coachz.biz" }

  initialize_with do
    attributes.deep_stringify_keys
  end
end
因为没有save方法,所以只能构建这些散列工厂

# Yes
jorb = FactoryBot.build(:job_application)

# No
jorb = FactoryBot.create(:job_application)
我发现自己经常这样做,所以我建立了一个字符串散列工厂来继承

factory :string_hash, class: Hash do
  initialize_with do
    attributes.deep_stringify_keys
  end
end

factory :job_application, parent: :string_hash do
  email { "jorb@coachz.biz" }
end
如果您想要嵌套哈希,我建议您创建其他工厂并将它们关联在一起。这允许您轻松地更改嵌套哈希中的值

关联默认为使用create,我们需要显式地构建关联。看

一定要问问自己,这样做是否有意义。这使得它们可以与普通工厂和验证等功能一起工作,您可以添加方法和所有好的东西

由于这是您在控制器中接收的数据,因此可能受益于验证和方法。看


你是在试图创建一个文字散列吗?不,多亏了你的评论,我才知道我做错了什么。但仍然无法编写测试,我将不得不再看一些。对不起,我想我没有完全理解您的建议。我的问题可能让你有些困惑。我想要的不是散列,而是以这种嵌套方式在控制器中接收数据参数。我需要创建一个工厂,该工厂将在测试时被控制器接受,它应该是一个散列,并传递到参数中。get:create,params:build:job\u应用程序。未试验过
# Yes
jorb = FactoryBot.build(:job_application)

# No
jorb = FactoryBot.create(:job_application)
factory :string_hash, class: Hash do
  initialize_with do
    attributes.deep_stringify_keys
  end
end

factory :job_application, parent: :string_hash do
  email { "jorb@coachz.biz" }
end
factory :address, parent: :string_hash do
  street { "Ahead St." }
  postal_code { "12345" }
end

factory :job_application, parent: :string_hash do
  association :address, strategy: :build

  email { "jorb@coachz.biz" }
  name { "Coach Z" }
end

build(:job_application,
  address: build(:address, street: "Sesame St.")
)
class JobApplication
  include ActiveModel::Model
  include ActiveModel::Validations

  attr_accessor :email, :name, :address

  validates :name, :email, presence: true
end

class Address
  include ActiveModel::Model

  attr_accessor :street, :postal_code
end

factory :address do
  street { "Ahead St." }
  postal_code { "12345" }
end

factory :job_application do
  # Can't save a Model either.
  association :address, strategy: :build

  email { "jorb@coachz.biz" }
  name { "Coach Z" }
end