[rspec-users] "user" received unexpected message :created_at with (no args)

David Chelimsky dchelimsky at gmail.com
Wed Jun 29 14:20:48 EDT 2011


On Jun 29, 2011, at 12:21 PM, S Ahmed wrote:

> My method looks like:
> 
> def self.can_do_this(user)
>   return false if user.nil?
>   (  (Time.now >= user.created_at) ? true : false  )
> end
> 
> my spec:
> 
> it "should allow you to do this" do
>   user = stub("user")
>   user.stub(:nil?).and_return(false)
>   user.stub(:created_at).and_return(Time.now)
> 
>   res = User.can_do_this(user)
>   res.should == true
> end
> 
> Running the spec I get:
> 
> Failer/Error: res = User.can_do_this(user)
> Stub "user" received unexpected message :created_at with (no args)
> 
> Any ideas?

I copied what you have as/is and added the User class and example group declarations:

class User
  def self.can_do_this(user)
    return false if user.nil?
    (  (Time.now >= user.created_at) ? true : false  )
  end
end

describe User do
  it "should allow you to do this" do
    user = stub("user")
    user.stub(:nil?).and_return(false)
    user.stub(:created_at).and_return(Time.now)

    res = User.can_do_this(user)
    res.should == true
  end
end

This passes, so either something is different about our environments or there is more going on than you are showing us. Please copy what I wrote above into its own file and run it and let us know if it passes or fails.

Off topic, some recommendations about the Ruby in your example:

1. user.stub(:nil?).and_return(false) is unnecessary. It is an object and it will return false to nil?.
2. you can declare a method stub in the declaration of the stub object:

  user = stub("user", :created_at => Time.now)

3. Asking an object if it is nil is unnecessary noise AND an unnecessary method call. This would be more terse and faster (as the evaluation happens in C in MRI, Java in JRuby, etc):

  return false unless user

4. A ternary that returns true or false is redundant. These two expressions are functionally equivalent:

(Time.now >= user.created_at) ? true : false
Time.now >= user.created_at

5. Given #3 and #4, the implementation of can_do_this can be reduced to:

  user && Time.now >= user.created_at

With those recommendations, the whole example can be reduced to:

class User
  def self.can_do_this(user)
    user && Time.now >= user.created_at
  end
end

describe User do
  it "should allow you to do this" do
    user = stub("user", :created_at => Time.now)
    User.can_do_this(user).should be_true
  end
end

We could talk about can_do_this wanting a "?" at the end, but my suspicion is that is not the real example you are working from.

HTH,
David


More information about the rspec-users mailing list