Samuel
Samuel

Reputation: 543

Rails RSpec controller test changes second attribute

I have a controller called "CrossLayerParamtersController". If one specified attribute (donor_layer) is updated. I want the attribute (donor_material) to be set to "0".

In the controller update method I'm checking if the donor_layer params are present and if they are the donor_material is set to 0:

Controller file:

cross_layer_parameter_controller.rb

 def update
    @stack = Stack.find(params[:stack_id])
    @cross_layer_parameter = CrossLayerParameter.find(params[:id])
    if params[:cross_layer_parameter][:donor_layer]
      @cross_layer_parameter.donor_material = 0
    end

    respond_to do |format|
      if @cross_layer_parameter.update(cross_layer_parameter_params)
        new_rows = render_to_string('stacks/_cross_layer_parameters.html.erb', layout: false, locals: { stack: @stack} )
        id = @cross_layer_parameter.id
        format.html { redirect_to(@stack) }
        format.json { render json: { new_rows: new_rows, id: id, status: 200 } }
      else
        format.html { redirect_to edit_stack_path(@cross_layer_parameter) }
        format.json { respond_with_bip(@cross_layer_parameter) }
      end
    end
  end

This is working as expected and I want to write an RSpec test in my controller tests that checks that. Until now I have:

RSpec test file:

cross_layer_parameter_controller_spec.rb

describe 'PUT #update' do
context "with params donor_layer or acceptor_layer" do
  before do
    post :update, params: { stack_id: @stack.id, donor_layer: 5, id: @cross_layer_parameter.id, cross_layer_parameter: FactoryGirl.attributes_for(:cross_layer_parameter) }
    @cross_layer_parameter.reload
  end

  it "should changed the donor material '0'" do
    expect(@cross_layer_parameter.donor_material).to eq 0
  end
end

end

I suspect FactoryGirl is messing it up but I'm not sure. Is there another way to test wittout using FactoryGirl? I've tried the put underneath but this didn't work.

post :update, params: { stack_id: @stack.id, donor_layer: 5, id: @cross_layer_parameter.id }

FactoryGirl file:

cross_layer_parameter.rb

require 'faker'

FactoryGirl.define do
  factory :cross_layer_parameter do
    donor_layer { Faker::Number.between(0, 10) }
    donor_material { Faker::Number.between(0, 10) }
    acceptor_layer { Faker::Number.between(0, 10) }
    acceptor_material { Faker::Number.between(0, 10) }
    interaction { Faker::Number.between(1, 9) }
    value { Faker::Number.decimal(2) }
  end
end

Upvotes: 1

Views: 137

Answers (1)

Argonus
Argonus

Reputation: 1035

You should not add params as params argument there. First part is type of action and action (put and update) and rest are params. Here is code sample for put update:

let(:params) { { attachment: '' } }
let(:action) { put :update, parent_id: parent.id, id: object.id, object: params }

Upvotes: 1

Related Questions