Lilp
Lilp

Reputation: 971

RSpec Expectations and ExpectationNotMetError

Hello I have been following a course to further my understanding of cucumber. The course is a little old so i have had to update some rspec syntax from should to expect but otherwise have been following it very carefully. I cannot get this recent test to pass and i am rather lost as to why. The error i am receiving is below. I understand it is receiving nil when it should be receiving 95 but i still do not understand why.

When They submitted an assignment    # features/step_definitions/teacher_grade_assignment.rb:6
    Then the assignment has a grade      # features/step_definitions/teacher_grade_assignment.rb:14

      expected: 95
           got: nil

      (compared using ==)
       (RSpec::Expectations::ExpectationNotMetError)
      ./features/step_definitions/teacher_grade_assignment.rb:15:in `/^the assignment has a grade$/'
      features/teacher_can_grade_assignment.feature:11:in `Then the assignment has a grade'

Failing Scenarios:
cucumber features/teacher_can_grade_assignment.feature:7 # Scenario: Teacher can grade assignment

teacher_grade_assignment.rb

Given(/^I have a student$/) do
    @teacher = Teacher.new
    @student = Student.new
end

Given(/^They submitted an assignment$/) do
  @teacher.submit_assignment(@student, Assignment.new)
end

When(/^I grade the assignment$/) do
  @teacher.record_grade(@student, 95)
end

Then(/^the assignment has a grade$/) do
    expect(@teacher.assignment_for_student(@student).grade).to eq(95)
end

student_assignment_steps.rb

Given(/^I am a student$/) do
  @student = Student.new #setting as an instance variable to access later on
  @teacher = Teacher.new
end

When(/^I submit an assignment to my teacher$/) do
    @assignment = Assignment.new
    @teacher.submit_assignment(@student, @assignment)
end

Then(/^my teacher should have my assignment$/) do
    expect(@teacher.assignment_for_student(@student)).to eq(@assignment)
end

teacher.rb

class Teacher 
    def initialize
        @assignments = {}
    end

    def record_grade(student, grade)
        assignment = @assignments[student] #assignment equal to assignments of the student
        assignment.grade = grade 
        @assignments[student] = assignment
    end 

    def submit_assignment(student, assignment)
        @assignments[student] = assignment
    end

    def assignment_for_student(student)
        @assignments[student]
    end
end

teacher_spec.rb

require_relative "../lib/teacher"
require "rspec"

describe Teacher do 
    it "should store assignments" do
        student = double
        assignment = double
        subject.submit_assignment(student, assignment)
        expect(subject.assignment_for_student(student)).to eq(assignment)
    end

describe "should record a grade" do 
    it "should record and the grade" do 
        student = double
        assignment = double
        expect(assignment).to receive(:grade=).with(95)
        subject.submit_assignment(student, assignment)
        subject.record_grade(student, 95)
    end
end
end

assignment_spec.rb

require_relative "../lib/assignment"

describe Assignment do 
    it "should store a grade" do 
        subject.grade = 60
        expect(subject.grade).to eq(60)
    end 
end 

assignment.rb

class Assignment
    attr_accessor :grade
end

student.rb

class Student
end

teacher_can_grade_assignment.feature

Feature: Teacher can grade assignment

    As a Teacher
    I can grade my students' assignments
    So that they can know their knowledge level

    Scenario: Teacher can grade assignment
        Given I have a student
        And They submitted an assignment
        When They submitted an assignment
        Then the assignment has a grade

Upvotes: 0

Views: 4401

Answers (2)

Frederick Cheung
Frederick Cheung

Reputation: 84132

Your assignment has no grade because the teacher never graded it: your feature doesn't call the "I grade the assignment step"

Upvotes: 2

berkes
berkes

Reputation: 27573

Your tests are telling you that @teacher.assignment_for_student(@student).grade is nil. Somehow it is not set up correctly. This is unexpected as you state, you expected it to be 95.

In TDD the best next step is to figure out more of the state in the failing test.

Add some extra (temporary) expectations to see what the state of your objects is in the failing step:

expect(@teacher.assignment_for_student(@student)).to eq(@assignment)
expect(@teacher.class_variable_get(:@assigments).to include(@assignment)

Even tests that you are sure will fail can often help a lot.

expect(@teacher.assignment_for_student(@student)).to be "failure"

By sprinkling such expectations around your steps, you can debug the state and see where the code is integrated wrong.

From your pasted code, I don't see anything wrong with the code immediately.

Upvotes: 1

Related Questions