0

I'm having trouble testing this code in rspec - based on the error the test gives me, I know the test is written (more or less) correctly - as the data it's expecting is correct, it's just not getting it for some reason. I should also note that the code works in the browser.

edit: apologies if this was unclear. In this controller (evaluations_controller), the user iterates through each student in a given group and evaluates their progress against a set of goals. In the new action, @student = groups.student.first - when evaluation data for that student has been saved successfully in the create action, the student_id incremented by 1, and the new student_id is passed to the new action again (so the next student can be evaluated) - this loops until there are no more students.

What I'm trying to test is that the student_id is being successfully incremented after evaluation has been saved in the create action.

Code:

def create
...
  if @evaluation.save
    @id = params[:student_id]
    @id = @id.to_i + 1
    redirect_to evaluate_path({ student_group_id: @student_group, student_id: @id})   
  else  
    ... 
  end
end

Rspec test:

it "should load the next student" do
  #set @id to current student.id +1
  @id = @student.id
  @id = @id.to_i + 1
  #post :create
  post :create, {student_group_id: @student_group, student_id: @student, evaluation: @attr}
  controller.params[:student_id].should eql @id                
end

Error:

Failure/Error: controller.params[:student_id].should eql @id expected: 2 got: "1"

dax
  • 10,779
  • 8
  • 51
  • 86
  • you never update the params, seems pretty clear – apneadiving Aug 19 '13 at 13:58
  • in the test, you mean? sorry, but how can i do that? – dax Aug 19 '13 at 14:06
  • It's not clear from your assertion what you're trying to test. Do you want to assert that the `student_id` that is passed to `evaluate_path` is one greater than the id that's passed into the create action? – gregates Aug 19 '13 at 14:06
  • if create is successful, the `student_id` increments by 1 and the `new` page is rendered again with the new `student_id` – dax Aug 19 '13 at 14:08
  • So you want to test that a student was saved? Is that what you mean by increment? Or the same student, its id increments by one? Your test is not very clear. – Mohamad Aug 19 '13 at 14:11

1 Answers1

1

Your code appears to be flawed, and consequently your test is not clear.

From gleaning over the code, I understand you want to use some type of next/previous student functionality. It appears you are hacking around your controller test to achieve that.

if @evaluation.save
    @id = params[:student_id]
    @id = @id.to_i + 1

You are manually calculating the next id. Ask yourself this: What happens if you are working with student.id 1, and you run this calculation, but student.id 2 has been deleted?

You get an ActiveRecord error.

You need a better way of pulling the next student. You should add an instance method to your Student model to handle that for you:

  def next
    Student.where(id: id).order("id ASC").first
  end

In your controller you can move to the next student as such:

redirect_to evaluate_path({ student_group_id: @student_group, student_id: @student.next.id})

Then your test should be much simpler.

Mohamad
  • 34,731
  • 32
  • 140
  • 219
  • it's a really good idea, thanks - it does make things much easier. At the moment however, it's not working. :/ it just returns `nil` `$ first_student.next` ==> `Student Load (0.4ms) SELECT "students".* FROM "students" WHERE "students"."id" = 0 ORDER BY id ASC LIMIT 1` `=> nil` – dax Aug 19 '13 at 14:37
  • in fact i think i made i typo in the method def, but now i fixed it and i'm just getting returned the same student_id (1) – dax Aug 19 '13 at 14:47
  • got it - http://stackoverflow.com/a/7394804/2128691 you still pointed me in the right direction though, thanks a lot! – dax Aug 19 '13 at 14:52