Mocha Release 0.9.7

Posted by James Mead Wed, 01 Jul 2009 11:52:49 GMT

Release Notes

  • Although I had provided a deprecation warning for people using the now renamed Mocha::Standalone, I had assumed people wouldn’t be explicitly loading the mocha/standalone.rb file. It turns out this assumption was incorrect at least in the case of RSpec. This is now fixed.

Posted in  | Tags , , , , ,  | no comments

Mocha Release 0.9.6

Posted by James Mead Mon, 29 Jun 2009 16:29:54 GMT

Release Notes

  • Version 2.0.1 of the test-unit gem introduced a private run_test method on TestCase which clashed with the public TestRunner#run_test method. So this latter method has been renamed to run_as_test.
  • Stop requiring rubygems – this should be an environmental choice for the user. This describes why requiring rubygems in your library code is a bad idea.
  • It seems like overkill to vendorize coderay and meta_project when they’re only needed to generate the examples for documentation and for publishing files on RubyForge. So I’m removing them and installing them locally as gems when I need them.
  • Added support for test-unit gem (version >= 2.0). Note that as with other versions of Test::Unit I’m completely replacing the TestCase#run method. Unfortunately in version 2.0.0 this method differs slightly from the same method in version 2.0.1 & 2.0.2, so we have to provide different implementations to ensure that the internal working of Test::Unit are not compromised by Mocha. Note also that unless the test-unit gem is loaded, requiring 'test/unit' leads to a mixture of standard library and gem classes being loaded causing errors. To avoid a dependency on rubygems, the gem is loaded only if MOCHA_OPTIONS is set to use_test_unit_gem – this option is only intended for use in running Mocha’s own tests. It might be worthwhile to create a shim gem like minitest_tu_shim to allow the test-unit gem to completely replace the standard library, but that’s a job for another day. My previous article on Test::Unit and MiniTest explains how the minitest-tu-shim works. The changes in the Rakefile are to make the default task run with the test-unit gem (version >= 2.0).
  • Renamed Mocha::Standalone to Mocha::API to better reflect its purpose. Added a deprecation warning for those who are referencing Mocha::Standalone.
  • Fix exception raised by HasEntry#matches? when first parameter is not a Hash (thanks to Taylor Barstow).
  • Ken Collins reported that Mocha is always loading MiniTest if it is available and loading it causes some Rails/ActionPack tests to break. I’ve removed the loading of MiniTest, but this now means the user has to ensure that if they want to use MiniTest in conjunction with Mocha, he must load MiniTest before loading Mocha.
  • Implemented Bacon integration (thanks to Ubiratan Pires Alberton), but this was then removed after deciding only to maintain integration with Test::Unit and MiniTest which are both Ruby standard libraries. See mailing list message for details.
  • Don’t monkey-patch MiniTest if it’s already been monkey-patched by Mocha.
  • Fixed bugMiniTest integration was counting ExpectationErrors as errors not failures.
  • Fixed bug – Some Bacon tests were failing in Ruby 1.9.1.
  • Chad Humphries pointed out that in Ruby 1.9.1, if you are not using Test::Unit or MiniTest, Mocha will attempt to load and monkey-patch Test::Unit. Mocha will now only monkey-patch Test::Unit and/or MiniTest if they have already been loaded. MiniTest tests will now run in both Ruby 1.8.6 (with MiniTest gem) and in Ruby 1.9.1 (with MiniTest standard library). See Lighthouse ticket.
  • Made Mocha compatible with minitest 1.4.0 and above (thanks to Denis Defreyne).

Posted in  | Tags , , , , ,  | 2 comments

National Express East Coast Ticket Options

Posted by James Mead Mon, 16 Mar 2009 12:55:33 GMT

Introduction

In the past, I’ve tended to buy Advance Single tickets for most of my journeys between Durham and London. This is usually the best option when booking a couple of months ahead, but when you have to book at shorter notice, I often overlook some of the return fares.

Despite the supposed simplification of UK train fares, it’s not straightforward to find all the relevant information in one place, so I thought I’d write it up here. I hope other people might find this useful, but please double-check with the NXEC website or a Travel Centre before spending any money.

Fares from Durham to London

Ticket Type Cost
Super Off-Peak Return 105.00
Off-Peak Return 163.80
Business Carnet 239.40
Anytime Return 266.00
First Class Anytime Return 370.00

Super Off-Peak Return Conditions

Northbound

Valid on any train from London King’s Cross except those timed to depart before 0929 Monday-Friday and from 1457-1859 inclusive, Monday-Thursday and from 1457-1815 on Fridays.

On a weekday, this means you can travel on the following direct services, departing London: 0930, 1130, 1230 & 1430, 18301, 1900, 19301, 2000, 2100.

Southbound

Valid on any train timed to arrive in London King’s Cross 1117 or later, Monday-Friday.

On a weekday, this means you can travel on the 0845 departure from Durham or any later train.

Off-Peak Return Conditions

Northbound

Valid on any train from London King’s Cross except those timed to depart 0645-0815 inclusive, Monday-Friday. Outward portions also barred 1559-1745 inclusive, Monday-Friday.

On a weekday, this means you can travel on the following direct services, departing London: 0615, 0830, 0930, 1130, 1230 & 1430, 1530, 1820, 1830, 1900, 19301, 2000, 2100.

Southbound

Valid on any train timed to arrive in London King’s Cross 1020 or later, Monday-Friday.

On a weekday, this means you can travel on the 0804 departure from Durham or any later train.

Business Carnet

  • 10 Anytime Return tickets for the price of 9.
  • To be used within a 3 month period.

References

1 Fridays only

Tags , , , , , , , , , , , , , ,  | 1 comment

National Hack the Government Day

Posted by James Mead Sun, 08 Mar 2009 11:06:53 GMT

I spent yesterday in the shiny new Guardian offices at Rewired State – National Hack the Government Day – which was a lot of fun, despite the early start. There was a really friendly atmosphere and lots of interesting projects going on.

ONS Graphs

I teamed up with Paul to work on some improvements for the Office for National Statistics website. We’d noticed that while there are many timeline datasets available on the site, the only way to view graphs of the data is to download a Windows application called Navidata. Although it’s free, this application is pretty clunky and hard to use and doesn’t generate very clear graphs. Also, rather obviously, it isn’t much use to Mac or Linux users.

Update: More about our hack from Paul – GreaseMonkey vs the ONS at Rewired State

So for the first part of our hack, in a fine example of post-modern programming, we decided to use JavaScript to generate a graph in the browser using the HTML table form of the data. Thanks to an article by Rebecca Murphey, we decided to use jQuery together with Rebecca’s graphTable jQuery plugin which uses the flot jQuery plugin to actually draw the graphs. We used the GreaseMonkey, the Firefox add-on, to write a little script to pull everything together.

So now anyone can use this script to view graphs of ONS timeline datasets :-

ONS Navigation

For the second part of our hack, we wanted to make a better way of navigating to the datasets. The current system uses a series of forms in a wizard-like experience which is quite hard to understand. Also, because of the form submissions (i.e. HTTP POSTs) required to access the datasets, there are no permanent URLs available to navigate directly to a dataset. We decided to try to remedy this by using Mechanize to scrape the timeline data from the website and then build a simplified static website using only links (i.e. HTTP GETs). However, we hit a snag in automatically submitting the last form in the wizard and ran out of time. I might try and have a go at this in the future if I get time.

We did notice that this last form had a hidden field containing what appeared to by a SQL query, making it ripe for SQL injection attack, but fortunately we managed to restrain ourselves.

Thanks to Ben Dodson & Paul Battley for the photos.

Tags , , , , , ,  | no comments

Uninstalling gems from .gem directory

Posted by James Mead Mon, 16 Feb 2009 15:56:48 GMT

I keep forgetting how to do this, so I thought I’d write myself some notes.

In a recent version, RubyGems changed it’s behaviour on gem install so that if it doesn’t have sufficient permission to install the gem files, it installs them in ~/.gem and generates a warning :-

  $ gem install <gem-name>
  WARNING:  Installing to ~/.gem since /usr/local/ruby-1.8.6-p287/lib/ruby/gems/1.8 and
    /usr/local/ruby-1.8.6-p287/bin aren't both writable.
  WARNING:  You don't have /Users/jamesmead/.gem/ruby/1.8/bin in your PATH,
    gem executables will not run.

Sometimes (e.g. when you forgot to prepend sudo) this isn’t what you want. However, it’s not obvious how to uninstall the gem again to correct your mistake :-

  $ gem uninstall <gem-name>
  ERROR:  While executing gem ... (Gem::InstallError)
    Unknown gem <gem-name> >= 0

To make this work, you need to specify the install-dir option :-

  $ gem uninstall <gem-name> --install-dir=~/.gem/ruby/1.8/
  Successfully uninstalled <gem-name>-x.y.z

Note that if you are using Ruby 1.9, it looks like the RubyGems directory path includes the point release version number e.g. 1.9.0 or 1.9.1.

Update: Prevention is better than cure. Coderr suggests protecting your ~/.gem directory.

Tags , , , , , , , ,  | 6 comments

Mocha Configuration

Posted by James Mead Mon, 09 Feb 2009 11:40:00 GMT

Introduction

In his recent look at Mocha’s internals, Brian Guthrie mentioned that he hadn’t realised it was possible to configure Mocha to warn or disallow mocking of non-existent methods. So I thought it was time I explained Mocha’s configuration settings. These configuration settings are all somewhat experimental and feedback on their effectiveness would be welcome.

There are 3 levels for all of the existing conditions :-

  # default behaviour
  Mocha::Configuration.allow(condition)

  # warning is displayed when condition is met
  Mocha::Configuration.warn_when(condition)

  # error is raised when condition is met
  Mocha::Configuration.prevent(condition)

Stubbing a non-existent method

This is useful if you want to ensure that methods you’re mocking really exist. A common criticism of unit tests with mock objects is that such a test may (incorrectly) pass when an equivalent non-mocking test would (correctly) fail. While you should always have some integration tests, particularly for critical business functionality, this Mocha configuration setting should catch scenarios when mocked methods and real methods have become misaligned.

  Mocha::Configuration.prevent(:stubbing_non_existent_method)

  class Example
  end

  class ExampleTest < Test::Unit::TestCase
    def test_example
      example = Example.new
      example.stubs(:method_that_doesnt_exist)
      # => Mocha::StubbingError: stubbing non-existent method:
      # =>   #<Example:0x593760>.method_that_doesnt_exist
    end
  end

Stubbing a method unnecessarily

This is useful for identifying unused stubs. Unused stubs are often accidentally introduced when code is refactored.

  Mocha::Configuration.prevent(:stubbing_method_unnecessarily)

  class ExampleTest < Test::Unit::TestCase
    def test_example
      example = mock('example')
      example.stubs(:unused_stub)
      # => Mocha::StubbingError: stubbing method unnecessarily:
      # =>   #<Mock:example>.unused_stub(any_parameters)
    end
  end

Stubbing a non-public method

Many people think that it’s good practice only to mock public methods. This is one way to prevent your tests being too tightly coupled to the internal implementation of a class. Such tests tend to be very brittle and not much use when refactoring.

  Mocha::Configuration.prevent(:stubbing_non_public_method)

  class Example
    def internal_method; end
    private :internal_method
  end

  class ExampleTest < Test::Unit::TestCase
    def test_example
      example = Example.new
      example.stubs(:internal_method)
      # => Mocha::StubbingError: stubbing non-public method:
      # =>   #<Example:0x593530>.internal_method
    end
  end

Stubbing Method on Non-Mock Object

If you like the idea of mocking roles not objects and you don’t like stubbing concrete classes, this is the setting for you. However, while this restriction makes a lot of sense in Java with its explicit interfaces, it may be moot in Ruby where roles are probably best represented as Modules. Anyway that’s probably a discussion for another day.

  Mocha::Configuration.prevent(:stubbing_method_on_non_mock_object)

  class Example
    def example_method; end
  end

  class ExampleTest < Test::Unit::TestCase
    def test_example
      example = Example.new
      example.stubs(:example_method)
      # => Mocha::StubbingError: stubbing method on non-mock object:
      # =>   #<Example:0x593620>.example_method
    end
  end

Tags , , , , , , , , , ,  | 1 comment

Mocha Internals under Scrutiny

Posted by James Mead Tue, 03 Feb 2009 20:49:28 GMT

I’ve just read Brian Guthrie’s recent article entitled Ioke mocking, Mocha as exemplar. Brian has volunteered to work on a mocking framework for Ola Bini’s Ioke. I’ve read bits and pieces on Ola’s blog about the development of Ioke, so I was very interested to see what Brian had to say. He makes some very valid comments; both about mocking in general and about the internals of Mocha.

Mocking in General

I agree with him about it being so easy to stub in prototype-based languages, but (as he says) mocking libraries offer more than just stubbing. One related problem is that different people mean different things when they talk about “mocking”. xUnit Test Patterns by Gerard Meszaros provides a useful breakdown of the different capabilities offered by different types of what he (more generically) calls Test Doubles :-

  • Dummy Object
  • Test Stub
  • Test Spy
  • Mock Object
  • Fake Object

In my LRUG presentation: An Introduction to Mock Objects in Ruby, I translated these different types of Test Doubles into Ruby examples which people might find helpful.

Mocha Internals

I’m glad that Brian drew some inspiration from reading the Mocha source code – I have to admit I went through a similar exercise with the jMock source code some time ago. So thanks to Nat & Steve for that.

Mocha (particularly the internals) has changed a lot since the early releases but, as Brian mentions, the original split between the so-called Mocha and Stubba components has not really been bridged internally. Reading this critique has just helped me realise that a mock object in Ruby is, after all, just an instance of a BlankSlate-like object and could therefore be approached with Stubba-like tactics (rather than the specialised Mocha-like tactics which are currently used). I think this could lead to a significant simplification of the code. Yay! I love open source :-)

As well as the welcome critique, Brian made some very pleasing comments :-

I’d happily recommend [Mocha] to others as a good example of how to pull off some hairy Ruby functionality without writing a whole lot of hairy Ruby code in the process.

Much of Mocha is like that: moderately sized, neither opaque in its density or transparent in its verbosity. Nice, I suppose, for my own definition of nice.

Reflections

I’m a fan of the Pragmatic Programmers suggestion to “learn a new programming language every year”. As an extension to this, I think there is some truth in what I think is a quote from Dan North : “everyone should write a mocking framework”. In any case, I certainly know that one of the most important things I’ve got out of writing Mocha is a deeper understanding of Ruby internals.

Lastly this seems like an opportune time to thank my former colleagues at Reevoo: Paul Battley, Chris Roos and especially Ben Griffiths for all their help and encouragement with Mocha.

Tags , , , ,  | no comments

Test::Unit and MiniTest with different Ruby versions

Posted by James Mead Mon, 02 Feb 2009 17:12:54 GMT

Introduction

In recent weeks, I’ve been trying to ensure that Mocha works with the new versions of Ruby as well as MiniTest, the Test::Unit replacement. I started getting very confused with all the different ways to write/run tests, so I made some notes for myself. In the wake of the release of Ruby 1.9.1, I thought these notes might be useful to others – so here they are.

I haven’t got into the MiniTest::Spec or MiniTest::Mock side of things, nor have I looked at other testing libraries like RSpec, Shoulda, Test/Spec, etc. Please let me know if you see any errors or omissions and I’ll update this article.

I’ve included the information about Ruby 1.9.0 for completeness, but most people will only be interested in the sections on 1.9.1 which is the “first stable release of Ruby 1.9 series”.

As I mentioned in the release notes, Mocha 0.9.5 should work with Test::Unit or MiniTest in Ruby 1.8.* or Ruby 1.9.1. It does not currently work in Ruby 1.9.0, but I won’t be making this a priority unless I have specific requests to do so.

Note that at some point MiniTest changed its name from MiniUnit.

Ruby 1.8 with Test::Unit standard library

The basics.

  require 'test/unit'

  class Ruby18TestUnitTest < Test::Unit::TestCase

Ruby 1.8 with MiniTest gem

If you can’t upgrade to Ruby 1.9, you can still use MiniTest by installing the gem. Note that you have to install the autorun exit hook manually for MiniTest – this is done automatically for Test::Unit when you require ‘test/unit’ – if you want the tests to be executed when the file run as a Ruby script.

  # gem install minitest

  require 'rubygems'
  gem 'minitest'
  require 'minitest/unit'

  MiniTest::Unit.autorun

  class Ruby18MiniTestGemTest < MiniTest::Unit::TestCase

Ruby 1.8 with MiniTest-Test::Unit shim

This takes things a step further by installing a shim gem which makes requiring ‘test/unit’ behave the same way as it does in a vanilla Ruby 1.9.1 installation i.e. Test::Unit becomes a thin wrapper around MiniTest. This means that you don’t have to change your tests to inherit from MiniTest::Unit::TestCase in order to use MiniTest. However, you should note that some of Test::Unit’s API (e.g. Test::Unit::TestResult) is no longer available. Note that you can reverse the effect of use_minitest yes using use_minitest no.

  # sudo gem install minitest_tu_shim
  # sudo use_minitest yes

  require 'rubygems'
  gem 'minitest'
  require 'test/unit'

  class Ruby18MiniTestTUShimTest < Test::Unit::TestCase

Ruby 1.9.0 with Test::Unit standard library

The Test::Unit standard library seems to be unchanged.

  require 'test/unit'

  class Ruby190TestUnitTest < Test::Unit::TestCase

Ruby 1.9.0 with Mini::Test standard library

An earlier version of MiniTest (i.e. Mini::Test) is also available as a standard library. Note the different directory, file, class & module names.

  require 'mini/test' # c.f. require 'minitest/unit' in Ruby 1.9.1

  Mini::Test.autorun

  class Ruby190MiniTestTest < Mini::Test::TestCase

Ruby 1.9.1 with Test::Unit standard library

Test::Unit is just a thin wrapper around MiniTest as described in Ruby 1.8 with MiniTest-Test::Unit shim

  require 'test/unit'

  class Ruby191TestUnitTest < Test::Unit::TestCase

Ruby 1.9.1 with MiniTest standard library

MiniTest is intended to be the default standard library to use for testing.

  require 'minitest/unit'

  MiniTest::Unit.autorun

  class Ruby191MiniTestTest < MiniTest::Unit::TestCase

Ruby 1.9.1 with Test::Unit gem

It is possible to use the classic Test::Unit by installing the gem. It looks like you need to specify version 1.2.3 to avoid picking up what appears to be some more significant changes in versions >= 2.0.

  # sudo gem install test-unit -v 1.2.3

  require 'rubygems'
  gem 'test-unit'
  require 'test/unit'

  class Ruby19TestUnitGemTest < Test::Unit::TestCase

Versions used for testing

  • OSX Leopard 10.5.6
  • Ruby 1.8.6 (2008-08-11 patchlevel 287)
  • Ruby 1.9.0 (2008-10-04 revision 19669)
  • Ruby 1.9.1p0 (2009-01-30 revision 21907)
  • minitest gem 1.3.1
  • minitest_tu_shim gem 1.3.0
  • test-unit gem 1.2.3

References

Tags , , , , , , , ,  | 2 comments

Mocha Release 0.9.5

Posted by James Mead Sun, 01 Feb 2009 12:55:57 GMT

Ruby 1.9 Compatibility

Note that Mocha should be compatible with Ruby 1.9.1 using MiniTest or Test::Unit. However, if you want to use Test::Unit, you will need to install the test-unit gem.

Release Notes

  • Fixed Lighthouse bug #32 – stub_everything should mean mock responds to anything.
  • Added Expectation#twice to improve readability. Thanks to pull request from Celestino Gomes.
  • In Ruby 1.9.1, requiring ‘test/unit’ loads a thin wrapper around MiniTest and Test::Unit::TestCase ends up inheriting from MiniTest::Unit::TestCase. So we need to avoid including the Mocha modules more than once to avoid nasty consequences. Thanks to Matthias Hennemeyer for help with this.
  • Ruby 1.9 includes rake, but not rake/contrib. For the moment I’ve moved the sshpublisher require into the only rake task that needs it, so that I can at least run the tests in Ruby 1.9. It looks like I will need to build a rake/contrib gem or similar to get this working properly.

Posted in  | Tags , , , , ,  | no comments

Climbing Back onto the Java Horse

Posted by James Mead Thu, 22 Jan 2009 19:20:38 GMT

I took a short break from job-hunting1 earlier today to see if I could still write Java code. After my Java rehab which consisted of 3+ years of writing Ruby, I was a bit unsure how much Java I would remember. To get started, I decided to try and set up Eclipse on my MacBook Pro. I ran into a few problems which I thought I’d document here in case it helps anyone else.

Installing Eclipse

I downloaded the Mac OS X version of “Eclipse IDE for Java EE2 Developers” from the Eclipse Downloads page and unpacked it into my Applications directory. For the record, I was running OSX 10.5.6 and downloaded version 3.4.1 of Eclipse.

But when I double-clicked to start the application, I got the following error message:-

eclipse-java-environment-startup-error

A Java Runtime Environment (JRE) or Java Development Kit (JDK) must be available in order to run Eclipse. No virtual machine was found after searching the following locations: etc, etc.

However, I was able to run the application from the command-line, which pointed to an environment problem. Reading the “Cannot find a VM” section of I unzipped Eclipse, but it won’t start. Why?, I decided I needed to explicitly specify the location of the JVM. It turned out there were a few gotchas. The OSX-specific bit of the installation README explains how to edit the eclipse.ini file within the Eclipse application bundle. Eclipsepedia explains the format of the -vm option :-

  • The -vm option and its value (the path) must be on separate lines.
  • The value must be the full absolute path to the Java executable, not just to the Java home directory.

So I added the following to my eclipse.ini and the application started up successfully :-

  
  -vm
  /System/Library/Frameworks/JavaVM.framework/Versions/1.5.0
  

Note: I think that the -vm option must come before the -vmargs option.

JUnit4 and jMock2

Next I decided to see if I could write a test using JUnit and jMock to drive out the design of a simple class. I downloaded the most recent stable version of jMock which was v2.5.1 and added the relevant jars to Eclipse so that they could be included in my project classpath :-

  • jmock-2.5.1.jar
  • hamcrest-core-1.1.jar
  • hamcrest-library-1.1.jar
  • jmock-junit4-2.5.1.jar

At this point everything was going quite smoothly – especially after I side-stepped some of Java’s purgatorial nonsense by re-learning the Eclipse keyboard shortcuts for “Quick Fix” and “Content Assist”. But now I decided I wanted to try using JUnit Java annotations for my tests :-

  
  import org.junit.Test;
  import org.junit.runner.RunWith;

  import org.jmock.Mockery;
  import org.jmock.Expectations;
  import org.jmock.integration.junit4.JUnit4Mockery;
  import org.jmock.integration.junit4.JMock;

  @RunWith(JMock.class)
  public class PublisherTest {

    Mockery context = new JUnit4Mockery();

    @Test 
    public void oneSubscriberReceivesAMessage() {
      ...
  

Unfortunately I got this error around the @RunWith(JMock.class) annotation :-

The type org.junit.internal.runners.JUnit4ClassRunner cannot be resolved. It is indirectly referenced from required .class files.

After bit of Googling, I worked out that I needed a newer version of JUnit than the one (v4.3.1) that came with Eclipse. So I downloaded JUnit v4.5 and swapped it into the classpath. Problem solved.

1 I was made redundant from Reevoo at the end of last year.

2 Because I love all that enterprise goodness ;-)

Tags , , , , ,  | 2 comments

Older posts: 1 2 3 ... 11