Perry Horwich
Perry Horwich

Reputation: 2846

How do I match this result in RSpec for my Controller test

I have a test that I believe should pass. The last line looks like this:

expect(assigns(@step)).to include @test_step_item

The test fails and outputs this:

  1) StepsController assigns the requested StepItem to @step
     Failure/Error: expect(assigns(@step)).to include @test_step_item

expected {"marked_for_same_origin_verification" => true, "step" => #<StepItem id: 1, type: "StepItem", note: "Could have a note", position: 1, name: nil, institution_id: 1, protocol_id: nil, created_at: "2014-09-26 14:57:11", updated_at: "2014-09-26 14:57:11", orientation_id: 1, sequence_id: 1>, "type" => "Step", "_optimized_routes" => true, "current_user" => nil}  
to include #<StepItem id: 1, type: "StepItem", note: "Could have a note", position: 1, name: nil, institution_id: 1, protocol_id: nil, created_at: "2014-09-26 14:57:11", updated_at: "2014-09-26 14:57:11", orientation_id: 1, sequence_id: 1>

       Diff:
       @@ -1,2 +1,6 @@
       -[#<StepItem id: 1, type: "StepItem", note: "Could have a note", position: 1, name: nil, institution_id: 1, protocol_id: nil, created_at: "2014-09-26 14:57:11", updated_at: "2014-09-26 14:57:11", orientation_id: 1, sequence_id: 1>]
       +"_optimized_routes" => true,
       +"current_user" => nil,
       +"marked_for_same_origin_verification" => true,
       +"step" => #<StepItem id: 1, type: "StepItem", note: "Could have a note", position: 1, name: nil, institution_id: 1, protocol_id: nil, created_at: "2014-09-26 14:57:11", updated_at: "2014-09-26 14:57:11", orientation_id: 1, sequence_id: 1>,
       +"type" => "Step",

     # ./spec/controllers/steps_controller_spec.rb:29:in `block (2 levels) in <top (required)>'
     # -e:1:in `<main>'

... which looks like something pretty close to what I want with:

{"marked_for_same_origin_verification" => true, "step" =>

prepended to the expected hash.

I've tried several RSpec matchers, like 'include' and 'match' but these don't pass. I tried using end_with like this:

  expect(assigns(@step)).to end_with @test_step_item

but still got this:

  1) StepsController assigns the requested StepItem to @step
     Failure/Error: expect(assigns(@step)).to end_with @test_step_item
       expected {"marked_for_same_origin_verification"=>true, "step"=>#<StepItem id: 1, type: "StepItem", note: "Could have a note", position: 1, name: nil, institution_id: 1, protocol_id: nil, created_at: "2014-09-26 15:03:02", updated_at: "2014-09-26 15:03:02", orientation_id: 1, sequence_id: 1>, "type"=>"Step", "_optimized_routes"=>true, "current_user"=>nil}   

to end with #<StepItem id: 1, type: "StepItem", note: "Could have a note", position: 1, name: nil, institution_id: 1, protocol_id: nil, created_at: "2014-09-26 15:03:02", updated_at: "2014-09-26 15:03:02", orientation_id: 1, sequence_id: 1>
# ./spec/controllers/steps_controller_spec.rb:28:in `block (2 levels) in <top (required)>'
# -e:1:in `<main>'

ADDENDUM
After trying jdenen's suggestion, things look closer, but still not passing. This:

expect(assigns(@step)["step"]).to include(@test_step_item)

yields this:

  1) StepsController assigns the requested StepItem to @step
     Failure/Error: expect(assigns(@step)["step"]).to include(@test_step_item)
       expected #<StepItem id: 1, type: "StepItem", note: "Could have a note", position: 1, name: nil, institution_id: 1, protocol_id: nil, created_at: "2014-09-26 15:34:09", updated_at: "2014-09-26 15:34:09", orientation_id: 1, sequence_id: 1> to include #<StepItem id: 1, type: "StepItem", note: "Could have a note", position: 1, name: nil, institution_id: 1, protocol_id: nil, created_at: "2014-09-26 15:34:09", updated_at: "2014-09-26 15:34:09", orientation_id: 1, sequence_id: 1>, but it does not respond to `include?`
       Diff:
       @@ -1,2 +1,2 @@
       -[#<StepItem id: 1, type: "StepItem", note: "Could have a note", position: 1, name: nil, institution_id: 1, protocol_id: nil, created_at: "2014-09-26 15:34:09", updated_at: "2014-09-26 15:34:09", orientation_id: 1, sequence_id: 1>]
       +#<StepItem id: 1, type: "StepItem", note: "Could have a note", position: 1, name: nil, institution_id: 1, protocol_id: nil, created_at: "2014-09-26 15:34:09", updated_at: "2014-09-26 15:34:09", orientation_id: 1, sequence_id: 1>

Am I supposed to convert the object @test_step_item to a string, modify that string, and then test it against the expect(assigns(@step)).to result or is there a better way?

Upvotes: 0

Views: 780

Answers (1)

Johnson
Johnson

Reputation: 1490

I would just drill into the returned Hash and validate against that.

expect(assigns(@step)["step"]).to include(@test_step_item)

EDIT

expect(assigns(@step)["step"]).to eq(@test_step_item)

I read your original failure message wrong. Include was the not the correct matcher. assigns(@step)["step"] should give you an exact match of @test_step_item.

Upvotes: 2

Related Questions