Mark Needham

Thoughts on Software Development

RSpec: Another newbie mistake

with 3 comments

We recently had a spec which was checking that we didn’t receive a call to a specific method on an object…

describe "Our Object" do
	it "should not update property if user is not an admin" do
		our_user = Factory("user_with_role_x)
		User.stub!(:find).and_return(our_user)
 
		user.stub!(:is_admin?).and_return(false)
		user.should_not_receive(:property)
	end
end

…where ‘property’ refers to a field in the users table. In the code ‘property’ would get set like this:

class ObjectUnderTest
 
	def method_under_test
		user = User.find 4
 
		if user.is_admin?
			user.property = "random value"			
		end
	end

That test always passed but when we wrote the test to check that ‘property’ would be set if the user was an admin we found that it always failed.

The mistake is quite simple – the method that we wanted to check was received is actually called ‘property=’ rather than ‘property’!

Changing the spec to read like this solves the problem:

describe "Our Object" do
	it "should describe something" do
		our_user = Factory("user_with_role_x)
		User.stub!(:find).and_return(our_user)
 
		user.stub!(:is_admin?).and_return(false)
		user.should_not_receive(:property=)
	end
end

It didn’t take that long to figure it out but this is certainly a mistake you wouldn’t be able to make in a statically typed language.

Written by Mark Needham

September 30th, 2010 at 7:03 am

Posted in Ruby

Tagged with

  • http://andypalmer.com Andy Palmer

    It’s possible that, in a statically typed language, I might have called the methods SetProperty and GetProperty, which might make the mistake easier to spot for someone who was used to that pattern (but no less likely to happen)
    I would imagine that the same holds true for someone with an appropriate amount of context in Ruby

  • http://betarelease.github.com Sudhindra Rao

    Hi Mark,
    What you are calling here is a method “def property=()” and what you were stubbing before was the method “def property”. “def property” does not take an argument hence the confusion. If you expected

    user.should_not_receive(:property).with(“something”)

    you could have received another type of error indicating more than required arguments

    So the error pertains to what you were stubbing and has nothing to do with dynamicity of the language.

    As an aside in rails every attribute will have a “def attribute” and a “def attribute=” method.

    -Sudhindra

  • http://www.markhneedham.com Mark Needham

    Ahhh ok well even a newbie mistake in the understanding of what I’d done wrong as well!