Just a short post about mocking/stubbing your Ruby functions. Let's have a class like this:
class ConfigurableClass
attr_reader :option
def configure_from_file(file)
json = JSON(IO.read(file))
@option = json['my']['option']
end
end
One way to test this would be to mock IO.read with Mocha
describe ConfigurableClass do
it "can configure from json" do
data = '{ "my": { "option" : "hello" } }'
IO.any_instance.expect(:read).with("x.json").returns(data)
cc = ConfigurableClass.new
cc.configure_from_file("x.json")
cc.option.should eq "hello"
end
end
This is tricky if your code does IO.read anywhere else which you obviously don't want to mock. However with some refactoring code is much cleaner.
class ConfigurableClass
attr_reader :option
def read_config_file(file)
IO.read(file)
end
def configure_from_file(file)
json = JSON(read_config_file)
@option = json['my']['option']
end
end
Then in the rspec it's easy to mock only function specific to ConfigurableClass.
describe ConfigurableClass do
it "can configure from json" do
data = '{ "my": { "option" : "hello" } }'
ConfigurableClass.any_instance.expect(read_config_file).with("x.json").returns(data)
cc = ConfigurableClass.new
cc.configure_from_file("x.json")
cc.option.should eq "hello"
end