lkahtz
lkahtz

Reputation: 4796

ArgumentError in rspec

I want to write some tree data structure in ruby. The class file:

class Tree
  attr_accessor :node, :left, :right
  def initialize(node, left=nil, right=nil)
    self.node=node
    self.left=left
    self.right=right
  end
end

The rspec file:

require 'init.rb'

describe Tree do
  it "should be created" do
    t2=Tree.new(2)
    t1=Tree.new(1)
    t=Tree.new(3,t1,t2)
    t.should_not be nil
    t.left.node should eql 1
    t.right.node should eql 2
  end
end

Rspec keeps complaining:

1) Tree should be created
     Failure/Error: t.left.node should eql 1
     ArgumentError:
       wrong number of arguments (0 for 1)
     # ./app/tree.rb:3:in `initialize'
     # ./spec/tree_spec.rb:9:in `block (2 levels) in <top (required)>'

Why?? I move the spec code into the class file and it works out. What is wrong?

Upvotes: 1

Views: 699

Answers (1)

Rob Davis
Rob Davis

Reputation: 15802

Believe it or not, the problem is two missing dots in your rspec. These lines:

t.left.node should eql 1
t.right.node should eql 2

should be this:

t.left.node.should eql 1
t.right.node.should eql 2

Insert that period before should, and your spec should pass.

Here's what's going on. The should method works on any value, but if you call it bare, like this:

should == "hello"

it will operate on the subject of your test. What's the subject? Well, you can set the subject to whatever you want using the subject method, but if you don't, rspec will assume the subject is an instance of whatever class is being described. It sees this at the top of your spec:

describe Tree

and tries to create a subject like this:

Tree.new

which blows up, since your initialize won't work without any arguments; it needs at least one. The result is a pretty cryptic error if you didn't intend to write a should with an implicit subject.

Upvotes: 2

Related Questions