如何为Rspec Controller #create Test生成具有嵌套属性的哈希值

时间:2013-12-27 01:26:31

标签: ruby-on-rails tdd rspec2 rspec-rails

我在Rspec中测试Rails 4控制器#create操作如下:

describe "POST #create" do    
    it "saves personality test responses in database" do
      expect {
        post :create, graduate_id: graduate, personality_test: attributes_for(...)
      }.to change(PersonalityTest, :count).by(1)
    end
end

注意,上面的attributes_for(...)是我正在努力的部分。为了让控制器创建一个新记录,我需要以这种格式传递一个哈希值(其中"personality_test_template_question_id""personality_test_template_answer_id"是现有模型的外键:

"personality_test"=>{
  "personality_test_template_id"=>"1", "personality_test_responses_attributes"=>{
    "0"=>{"personality_test_template_question_id"=>"1", "personality_test_template_answer_id"=>"2"}, 
    "1"=>{"personality_test_template_question_id"=>"2", "personality_test_template_answer_id"=>"9"}, 
    "2"=>{"personality_test_template_question_id"=>"3", "personality_test_template_answer_id"=>"14"}, 
    "3"=>{"personality_test_template_question_id"=>"4", "personality_test_template_answer_id"=>"21"}, 
    "4"=>{"personality_test_template_question_id"=>"5", "personality_test_template_answer_id"=>"27"}, 
    "5"=>{"personality_test_template_question_id"=>"6", "personality_test_template_answer_id"=>"33"}, 
    "6"=>{"personality_test_template_question_id"=>"7", "personality_test_template_answer_id"=>"38"}, 
    "7"=>{"personality_test_template_question_id"=>"8", "personality_test_template_answer_id"=>"46"}, 
    "8"=>{"personality_test_template_question_id"=>"9", "personality_test_template_answer_id"=>"54"}, 
    "9"=>{"personality_test_template_question_id"=>"10", "personality_test_template_answer_id"=>"58"}, 
    "10"=>{"personality_test_template_question_id"=>"11", "personality_test_template_answer_id"=>"64"}, 
    "11"=>{"personality_test_template_question_id"=>"12", "personality_test_template_answer_id"=>"70"}, 
    "12"=>{"personality_test_template_question_id"=>"13", "personality_test_template_answer_id"=>"76"}, 
    "13"=>{"personality_test_template_question_id"=>"14", "personality_test_template_answer_id"=>"83"}, 
    "14"=>{"personality_test_template_question_id"=>"15", "personality_test_template_answer_id"=>"86"}, 
    "15"=>{"personality_test_template_question_id"=>"16", "personality_test_template_answer_id"=>"92"}, 
    "16"=>{"personality_test_template_question_id"=>"17", "personality_test_template_answer_id"=>"101"}, 
    "17"=>{"personality_test_template_question_id"=>"18", "personality_test_template_answer_id"=>"107"}, 
    "18"=>{"personality_test_template_question_id"=>"19", "personality_test_template_answer_id"=>"110"}, 
    "19"=>{"personality_test_template_question_id"=>"20", "personality_test_template_answer_id"=>"119"}, 
    "20"=>{"personality_test_template_question_id"=>"21", "personality_test_template_answer_id"=>"122"}, 
    "21"=>{"personality_test_template_question_id"=>"22", "personality_test_template_answer_id"=>"132"}, 
    "22"=>{"personality_test_template_question_id"=>"23", "personality_test_template_answer_id"=>"137"}, 
    "23"=>{"personality_test_template_question_id"=>"24", "personality_test_template_answer_id"=>"140"}, 
    "24"=>{"personality_test_template_question_id"=>"25", "personality_test_template_answer_id"=>"146"}, 
    "25"=>{"personality_test_template_question_id"=>"26", "personality_test_template_answer_id"=>"152"}, 
    "26"=>{"personality_test_template_question_id"=>"27", "personality_test_template_answer_id"=>"162"}, 
    "27"=>{"personality_test_template_question_id"=>"28", "personality_test_template_answer_id"=>"165"}, 
    "28"=>{"personality_test_template_question_id"=>"29", "personality_test_template_answer_id"=>"173"}, 
    "29"=>{"personality_test_template_question_id"=>"30", "personality_test_template_answer_id"=>"177"}
  }
}

我不清楚以这种格式生成哈希的正确方法是什么。我尝试过FactoryGirl attributes_for方法,但它不会为嵌套工厂生成属性。任何提示都将受到高度赞赏。

谢谢!

1 个答案:

答案 0 :(得分:0)

我能够通过手动组装属性来重现这种类型的哈希格式:

describe "POST #create" do
  let(:valid_attributes) do
    attributes_for(:personality_test).merge(personality_test_template_id: 1,
      personality_test_responses_attributes: attributes_for_list(:personality_test_response, 30) 
    ) 
  end

  it "saves personality test responses in database" do
    expect{ 
      post :create, graduate_id: graduate, personality_test: valid_attributes 
    }.to change(PersonalityTest, :count).by(1)
  end
end

这些是我的工厂:

FactoryGirl.define do
  factory :personality_test do 
    ignore do
      questions_count 30
    end

    after(:build) do |pt, evaluator|
      pt.personality_test_template = PersonalityTestTemplate.find(1)
      pt.personality_test_responses = build_list(:personality_test_response, 
        evaluator.questions_count, personality_test: pt)
    end

  end

  factory :personality_test_response do
    personality_test
    sequence(:personality_test_template_question_id)
    sequence(:personality_test_template_answer_id, 1) { |n| n*6-3}
  end
end

请注意,在这种情况下,来自RSpec的请求头中的参数哈希与来自应用程序视图本身的原始参数哈希在某种意义上略有不同,即RSpec不生成伪数组(例如{{ 1}})用于嵌套属性。相反,它生成一个常规的哈希属性数组,它仍然可以正常工作。这是我从RSpec获得的:

{ "0" => {...}, "1"=> {...}... }

希望这有助于某人。