adrift on a cosmic ocean

Writings on various topics (mostly technical) from Oliver Hookins and Angela Collins. We have lived in Berlin since 2009, have two kids, and have far too little time to really justify having a blog.

In-depth testing with Mocha

Posted by Oliver on the 25th of February, 2011 in category Tech
Tagged with: mochamockingpuppetruby

I've recently been satisfying my need for more programming time and reading up on some of the aspects which really complete a good application, like adequate organisation, good design and reusability of library functions, error handling and of course testing. I've been using Cucumber for a while now in conjunction with Puppet which represents the BDD aspect, but haven't really delved into TDD until now since I'm actually actively writing Ruby.

The code I'm working on had a basic set of Test::Unit tests, which I've added to for my additions to the codebase and I've been trying to extend some of the testing as much as possible while not turning it into a rabbit hole. Since this application interacts with Puppet and files on disk, testing some aspects is just plain impossible without going to extraordinary measures to hack around the interaction with external libraries, files etc. That's where Mocha steps in.

OK, so mocking is just another area of technology that I'm years behind in, but I'm not sure I had use for it before. I'll be the first to admit that the syntax confused the hell out of me the first time I saw its usage in the Puppet test suite, but I think I "get it" now, and it is certainly delivering the functionality I need.

Consider a situation where we want to test some aspect of an application that relies on Puppet. I'll use IRB here to demonstrate:

irb(main):001:0> require 'rubygems'
=> true
irb(main):002:0> require 'mocha'
=> true
irb(main):003:0> require 'puppet'
=> true
irb(main):004:0> Puppet.parse_config
=> #<EventLoop::Timer:0x2ae5349457e8 ....
irb(main):005:0> Puppet[:vardir]
=> "/home/ohookins/.puppet/var"
irb(main):006:0> Puppet.expects(:[]).with(:vardir).returns('/tmp/foo')
=> #<Mocha::Expectation:0x2ae534937c60 ....
irb(main):007:0> Puppet[:vardir]
=> "/tmp/foo"

How cool is that? Yes of course, we could have fed Puppet a custom configuration file or set the configuration parameter ourselves, but if our code actually calls Puppet.parse_config then our efforts are lost, since our test setup code is run before this time. Mocha magically sets the stage for testing where we rig up the appropriately faked environment so we can only test the core functionality of that part of the code.

I'm exploring some slightly more complex use cases now with Mocha, but it is another valuable tool to add to my programmer's toolkit.

© 2010-2018 Oliver Hookins and Angela Collins