Archive for April, 2008

Ruby mock instance

Tuesday, April 29th, 2008

The common pattern for mocking class instances in Ruby involves setting an expectation on the new method of the class to return an object of the specified type. Consider the following User and Account classes.

class User
  attr_reader :name, :email

  def initialize(name, email)
    @name, @email = name, email
  end

  def contact
    send_email(@email)
  end
end

class Account
  def self.create(name, email)
    user = User.new(name, email)
    user.contact
  end
end

The test for the Account#create method would look like this:

require "rubygems"
require "mocha"
require "test/unit"

class AccountTest < Test::Unit::TestCase
  def test_emails_user_on_account_creation
    user = User.new("", "")
    user.expects(:contact)
    User.expects(:new).with("Kirk", "kirk@metallica.com").returns(user)
    Account.create("Kirk", "kirk@metallica.com")
  end
end

As an alternative, and this is the version I see most often used, a duck typed mock can be used in the place of the “real” User object.

class AccountTest < Test::Unit::TestCase
  def test_emails_user_on_account_creation
    user = mock
    user.expects(:contact)
    User.expects(:new).with("Kirk", "kirk@metallica.com").returns(user)
    Account.create("Kirk", "kirk@metallica.com")
  end
end

Both implementations have some potentially undesirable issues worth taking into consideration. None of the two is DRY, since in both cases we need to set a bespoke expectation for the object’s instantiation. In the first example, we are actually instantiating a “real” User. This compromises the dependency neutrality of the test, coupling it with User’s initialization implementation. The second example, despite its relative convenience, doesn’t fully respect the contract between Account and User. The interaction specification is inaccurate, because, as far as the application code under test is concerned, User#new doesn’t return an object of type Mocha::Mock, it returns an instance of User.

The following code can be useful in an effort to DRY up code as the one under discussion, whilst driving such interaction specifications closer to the actual contracts they are meant to express.

class Object
  def self.mock_instance(*args)
    class_eval do
      alias original_initialize initialize
      def initialize()end
    end

    instance = new
    expects(:new).with(*args).returns(instance)

    class_eval do
      alias initialize original_initialize
      undef original_initialize
    end

    return instance
  end
end

Here is how AccountTest can be written with the above Mocha extension in place.

class AccountTest < Test::Unit::TestCase
  def test_emails_user_on_account_creation
    User.mock_instance("Kirk", "kirk@metallica.com").expects(:contact)
    Account.create("Kirk", "kirk@metallica.com")
  end
end

If RSpec is your flavor, the same can be achieved with minor modifications in the Spec::Mocks::Methods module.

module Spec::Mocks::Methods
  def mock_instance(*args)
    class_eval do
      alias original_initialize initialize
      def initialize()end
    end

    instance = new
    should_receive(:new).with(*args).and_return(instance)

    class_eval do
      alias initialize original_initialize
      undef original_initialize
    end

    return instance
  end
end

With the above we can use mock_instance in specs as such.

describe Account do
  it "should email user on account creation" do
    User.mock_instance("Kirk", "kirk@metallica.com").should_receive(:contact)
    Account.create("Kirk", "kirk@metallica.com")
  end
end

Event registry

Tuesday, April 22nd, 2008

During projects I’ve worked on which involved coding JavaScript, I’ve had positive experiences enjoying the event driven nature of the language and some bad, especially after code bases grew larger with events firing left and right, producing side effects which were difficult to manage or track down. During the bad days, a centralized way of managing events was often brought up in conversations with colleagues as a means of managing the issue.

I’ve long been a fan of the event driven style of programming as a particularly useful alternative promoting loose coupling of system components. Below is the code for a Ruby module which, when included, enables classes to act as event dispatchers. Other classes can subscribe to the events and be notified when an event occurs.

module EventDispatcher
  module ClassMethods
    attr_reader :listeners

    def subscribe(event, &callback)
      @listeners ||= {}
      (@listeners[event] || @listeners[event] = []) << callback
    end

    private

    def clear_listeners!
      @listeners = {}
    end
  end

  def self.included(receiver)
    receiver.extend(ClassMethods)
  end

  def notify(event, *args)
    self.class.listeners[event].each {|callback| callback[*args]}
  end
end

Let’s consider an example application where the resource management department of an organization hires recruits and upon admission notifies interested services to take relevant action.

class RM
  include EventDispatcher

  def hire(name)
    notify(:new_recruit, name)
  end
end

What is especially interesting here is how the RM class doesn’t need to know anything about any interested listeners. In order to test RM, it suffices to ensure that a notification is sent upon calling the hire method.

def test_rm_notifies_on_new_hire
  service = mock
  service.expects(:new_recruit).with("name")
  RM.subscribe(:new_recruit) {|name| service.new_recruit(name)}
  RM.new.hire("name")
end

Typically, listeners would directly register their interest to the event by subscribing to it. Let’s imagine a welcoming letter is issued to new recruits the moment they join the organization.

class WelcomeLetterService
  RM.subscribe(:new_recruit) {|name| greet(name)}

  def self.greet(name)
    "Welcome, #{name}!"
  end
end

The first thing to notice is WelcomeLetterService’s direct coupling to RM. Additionally, a code base heavily employing this strategy might suffer ill effects similar to the ones described in the JavaScript inspired first paragraph of this article. Allowing a centralized option for event registration and management could serve as possible remedy to the issue.

module EventRegistry
  def register_event_listeners
    RM.subscribe(:new_recruit) {|name| WelcomeLetterService.greet(name)}
  end

  extend self
end

The EventRegistry module acts as a centralized mechanism for declaring which listeners subscribe to which events. On top of that, the WelcomeLetterService is now completely oblivious to the RM class.

class WelcomeLetterService
  def self.greet(name)
    "Welcome, #{name}!"
  end
end

Due to the level of decoupling achieved, testing these two components becomes particularly easy.

def test_welcome_letter_service_greets_by_name
  assert_equal(WelcomeLetterService.greet("Name"), "Welcome, Name!")
end

def test_event_subscription_wiring
  WelcomeLetterService.expects(:greet).with("name")
  RM.expects(:subscribe).with(:new_recruit).yields("name")
  EventRegistry.register_event_listeners
end

All this ties well with the philosophy behind Synthesized Testing, where a coherent collection of lightweight tests becomes a major factor of confidence that the system under test is complete, reducing the need for complex overarching tests.

Erubis with Sinatra

Sunday, April 20th, 2008

Sinatra doesn’t yet seem to come with built in support for Erubis. If you want the relative speed bump of Erubis over standard ERB for your Sinatra application, the code below should do the trick.

module Sinatra::Erb
  def erb(content, options={})
    begin
      require 'erubis'
      @@erb_class = Erubis::Eruby
    rescue LoadError
      require "erb"
      @@erb_class = ::ERB
    end
    render(:erb, content, options)
  end

  private

  def render_erb(content, options = {})
    @@erb_class.new(content).result(binding)
  end
end

Application code will not require any modifications, Sinatra will use Erubis if the gem is found in the load path.

Merb: render_deferred and render_then_call

Thursday, April 17th, 2008

Following the post on non blocking merb actions, it’s worth mentioning the Merb::ControllerMixin module, its render_deferred and render_then_call methods in particular.

render_deferred accepts a block argument, a proc that will be called outside the dispatch mutex, releasing the merb thread lock.

class MyController < Merb::Controller
  def hello
    render "hello"
  end

  def dont_wait_to_hello
    render_deferred { VerySlow.hello }
  end
end

Calls to /my_controller/hello, subsequent to requests to /my_controller/dont_wait_to_hello, will not have to wait for the latter to complete before being served.

As an interesting caveat, because execution of the proc is outside merb’s control, any exceptions raised in the block passed to render_deferred will not be rescued and redispatched, which suggests that custom error handling needs to be in place.

render_then_call accepts two arguments, a string that will be returned immediately as a response to the client and a block to be called after the string has been returned.

class MyController < Merb::Controller
  def receive_order
    render_then_call("Your pizza is in the oven.") do
      bake_pizza
      deliver_pizza
    end
  end
end

In this case, the specified message will be immediately returned, while the long running proc will be scheduled and executed by Mongrel, allowing orders to keep coming through a single application instance.

Non blocking merb actions

Wednesday, April 16th, 2008

One of the most powerful features in merb is an action’s ability to return a proc, thus releasing the controller block and transferring control to the application server which will be able to handle requests in a parallel manner.

Consider the following controller.

class MyController < Application
  def hello
    render "hello"
  end

  def wait_and_hello
    sleep 10
    render "hello"
  end

  def dont_wait_to_hello
    proc { sleep 10; p "hello" }
  end
end

Start merb and access http://localhost:4000/my_controller/hello after visiting http://localhost:4000/my_controller/wait_and_hello. Ten seconds will pass before /my_controller/hello is served. A request to /my_controller/hello will be served immediately regardless of whether a preceding request to /my_controller/dont_wait_to_hello has completed.

Synthesized Testing slides

Thursday, April 10th, 2008

For interested parties, here’s the latest Synthesized Testing slide deck.

Thin, Mongrel, Rack and performance

Thursday, April 3rd, 2008

I just ran a crud and unscientific test to satisfy my curiosity in regards to the speed difference between Thin and Mongrel.

I used Rack for convenience. This probably skews the results.

require "rubygems"
require "rack"

def run(server)
  require server
  s = Rack::Handler.const_get("#{server.capitalize}")
  app = proc {|env| [200, {"Content-Type" => "text/plain"}, "hello"]}
  s.run(app,:Host => ‘127.0.0.1′, :Port => 2323)
end

run “thin”
# run “mongrel”

I wrote a simple HTTP client sending one thousand consecutive, non simultaneous requests.

require "net/http"

before = Time.now
1000.times {Net::HTTP.new('127.0.0.1', 2323).request_get('/')}
p "#{1000/(Time.now - before)} requests per second"

The results… Thin did around 1160 requests per second, whereas Mongrel did 1220 on average.

Interestingly, when I added Rack::Lint to the mix, Thin dropped to about 640 requests per second and Mongrel dropped to 685.

s.run(Rack::Lint.new(app),:Host => '127.0.0.1', :Port => 2323)

Bearing in mind that these are non concurrent requests and that I’m running both the server and client on my Laptop (a 2.2 GHz 2GB RAM MacBook Pro) and that Rack is included in the stack, it seems that Mongrel has outperformed Thin. The most interesting, albeit accidentally discovered, observation however is the grave hit on performance noted when Rack::Lint becomes part of the equation.

Nu Language Event Dispatcher

Tuesday, April 1st, 2008

Nu is an interpreted object oriented language built on top of Objective C, with its syntax and several of its mechanics coming from Lisp, whilst being inspired by Ruby’s philosophy.

The Event Dispatcher example is one of my favorite when trying out a new language. I choose it because it’s representative of a number of programming language core topics such as lists, maps, closures, OO, etc.

I recently spent a short while porting the IO Language Event Dispatcher example in Nu and will be going over my experiment in this article.

Bellow is the code for the EventDispatcher class.

(class EventDispatcher is NSObject
  (- (id) initialize is
    (set @listeners (dict))
      self)

  (- (void) subscribe:(id)event callback:(id)callback is
    (unless (@listeners objectForKey:event)
      (@listeners setObject:(array) forKey:event))
      ((@listeners objectForKey:event) << callback))

  (- (void) notify:(id)event withArgs:(id)args is
    ((@listeners objectForKey:event) each: (do
      (callback) (callback args)))))

There are two prominent methods in this class, namely subscribe and notify.

The subscribe method takes two arguments, the event we’re subscribing to and a callback to be invoked every time the specified event takes place. The @listeners dictionary is constructed using the dict directive, which is shorthand for creating an NSCFDictionary instance. For each event, we maintain an array of callbacks. Like dict, array is available for conveniently creating NSCFArray instances.

Whenever notify is invoked with an event and the relevant arguments, we iterate invoking any callbacks registered for the given event, passing the provided arguments to each.

There are two ways that I know of that will allow classes to act as event dispatchers, inheritance being the first.

(class Factory is EventDispatcher
  (ivars)

  (- (void) produce:(id)color is
    (puts "#{color} product produced")
    (self notify:"new product" withArgs:color)))

Here, we create a Factory class which extends EventDispatcher and we define a produce method which notifies listeners that have subscribed to the “new product” event.

Composition is the second, and my preferred, option.

(class Factory is NSObject
  (ivars)

  (- (void) produce:(id)color is
    (puts "#{color} product produced")
    (self notify:"new product" withArgs:color)))

(Factory include:EventDispatcher)

Classes in Nu can be used in a manner similar to that of Module mix-ins in Ruby. Every object in Nu has an include method which will make a class’s instance methods available in another class. The advantage here is that we didn’t have to change Factory’s inheritance tree.

Following is a potential event listener that subscribes to the “new product” event and prints out a message every time the event is fired.

(class ProductWatcher is NSObject
  (- (id) watch is
    (factory subscribe:"new product" callback:(do (color)
      (puts "I see a #{color} product")))))

To run the example, we can instantiate a Factory and a ProducWatcher and fire a few events.

(set factory ((Factory new) initialize))
((ProductWatcher new) watch)

(factory produce:"black")
(factory produce:"red")
(factory produce:"blue")

The results look like this:

black product produced
I see a black product
red product produced
I see a red product
blue product produced
I see a blue product

There are a lot of reasons as to why I have time for Nu, its combining 3 of my favorite languages not included, greatly simplifying Cocoa development for native Mac and iPhone applications and Objective C’s excellent multi-core support to name but a few.