1
votes

I have an rspec test on a pure Ruby model:

require 'spec_helper'
require 'organization'

describe Organization do
  context '#is_root?' do
    it "creates a root organization" do
      org = Organization.new

      expect { org.is_root?.to eq true }
    end
 end
end

My organization model looks like this:

class Organization
  attr_accessor :parent

  def initialize(parent = nil)
    self.parent = parent
 end
end

The output when running the tests:

bundle exec rspec spec/organization_spec.rb:6
Run options: include {:locations=>{"./spec/organization_spec.rb"=>[6]}}
.

Finished in 0.00051 seconds
1 example, 0 failures

When I run the test, it passes, despite the fact that the method is_root? doesn't exist on the model. I usually work in Rails, not pure Ruby, and I've never seen this happen. What is going on?

Thanks!

2
can you post the output after you run the tests in terminal - cvibha
You could also start a rails console and ask o.methods.select do |m| m.match /root/ end to verify your assumption about is_root? - Patru
Apparently it's having the test inside expect{}. When I puts org.method(:is_root?) I get a failure: 1) Organization#is_root? creates a root organization Failure/Error: org.method(:is_root?) NameError: undefined method is_root?' for class Organization' # ./spec/organization_spec.rb:10:in method' # ./spec/organization_spec.rb:10:in block (3 levels) in <top (required)>' - rainslg
Patru, since this is not a Rails app, but pure Ruby, there is no rails console available. - rainslg

2 Answers

4
votes

It should be:

expect(org.is_root?).to eq true

When you pass block to expect it is being wrapped in ExpectationTarget class (strictly speaking BlockExpectationTarget < ExpectationTarget). Since you didn't specify what you expect from this object, the block is never executed, hence no error is raised.

2
votes

You are passing a block to expect, which is never being called. You can see this by setting an expectation on that block

expect { org.is_root?.to eq true }.to_not raise_error

  1) Organization#is_root? creates a root organization
     Failure/Error: expect { puts "HI";org.is_root?.to eq true }.to_not raise_error
       expected no Exception, got #<NoMethodError: undefined method `is_root?' for #<Organization:0x007ffa798c2ed8 @parent=nil>> with backtrace:
         # ./test_spec.rb:15:in `block (4 levels) in <top (required)>'
         # ./test_spec.rb:15:in `block (3 levels) in <top (required)>'
     # ./test_spec.rb:15:in `block (3 levels) in <top (required)>'

Or by just putting a plain raise or puts inside the block, neither of which will be called:

expect { puts "HI"; raise; org.is_root?.to eq true }

The block form is used for expecting that a piece of code raises an exception or not. The correct syntax for checking values is:

expect(org.is_root?).to eq(true)