Friday, September 26, 2008

mocha_mock_path error in your tests

If you use stubs in your Mocha tests but they break because of this error:

ActionView::TemplateError: undefined method `mocha_mock_path'


Check that you also stub the class method.


stub(:title => 'a title', :class => News)

Friday, September 19, 2008

Tip about encapsulation

I like this simple and practical Kent Beck's tip about encapsulation (from Fowler's Getter Erradicator article):

...always beware of cases where some code invokes more than one method on the same object...


It's not a rule but I think it can be considered one more smell to have in mind.

Wednesday, September 10, 2008

Stubbing/Mocking constants with Mocha

As far as google told me, it seems you can't use Mocha against constants.
One alternative proposed is changing the constant in the test where you need it like these:

class Module
def redefine_const(name, value)
__send__(:remove_const, name) if const_defined?(name)
const_set(name, value)
end
end
And inside the test case you change the constant to what you need and restore it after the test ends:

Object.redefine_const(:RAILS_ENV, 'production')
But if you can control the code that uses the constant there's a more clean way. Just wrap it in a method and get the constant through the method. During testing you just mock the method:

class A
def rails_env
RAILS_ENV
end
#...some more code that gets the constant RAILS_ENV using the method rails_env...
end
And then in your test you just do a normal expectation:

A.any_instance.expects(:rails_env).returns 'production'
You could even have some module that wraps all useful constants in your app, so constant dependent code gets easily testable and clean.

Wednesday, September 3, 2008

Singleton class magic without using singleton classes

Excellent posts here and here by Jay Fields where he gives an alternative to use singleton classes.

Instead of doing this:

class << self
def hi
puts 'Hi'
end
end
You do this:

mod = Module.new do
def hi
puts 'Hi'
end
end
extend mod