IronRuby 0.5 was released yesterday. You can download it on codeplex. This post will explain how you setup your ironruby environment to use it for testing existing CLR based assemblies. We’ll touch installing gems using rake and most importantly writing a test for a CLR based class where we’ll mock out the dependencies.
The first thing you need to do is download IronRuby. After downloading you can extract it to a location on your hard drive. I extracted mine to C:\ironruby
Now we need to add the path to ir.exe to our PATH variable so we can use it from the command-line. And that is all there is to it to install ironruby on your machine. Now we need to get the necessary gems onto our system. We’ll need bacon and caricature.
Open a console and type the following:
igem list will show you a list of the gems you have installed on your system.
igem install will fetch and install a gem on your system. To install the gems we’re going to need we need to execute the command
igem install bacon caricature
That will result in the following output:
+ C:\tools
» cmd
Microsoft Windows [Version 6.1.7100]
Copyright (c) 2009 Microsoft Corporation. All rights reserved.
C:\tools>where ir
C:\ironruby\bin\ir.exe
C:\tools>exit
+ C:\tools
» igem list
*** LOCAL GEMS ***
+ C:\tools
» igem install bacon caricature
Successfully installed bacon-1.1.0
Successfully installed caricature-0.6.0
3 gems installed
Installing ri documentation for bacon-1.1.0...
Installing ri documentation for caricature-0.6.0...
Installing RDoc documentation for bacon-1.1.0...
Installing RDoc documentation for caricature-0.6.0...
If you would try to execute ibacon at this point that would work. We’ll need to create 2 small files to get ibacon to work. In the bin directory of ironruby I created 2 files one called ibacon and the other one is ibacon.bat
#!C:/ironruby/bin/ir.exe
#
# This file was generated by RubyGems.
#
# The application 'bacon' is installed as part of a gem, and
# this file is here to facilitate running it.
#
require 'rubygems'
version = ">= 0"
if ARGV.first =~ /^_(.*)_$/ and Gem::Version.correct? $1 then
version = $1
ARGV.shift
end
gem 'bacon', version
load 'bacon'
@ECHO OFF
@"ir.exe" "%~dpn0" %*
At this point you’re ready to start writing specs with bacon and caricature. Let’s look at an example I wrote for the controller factory for ironruby mvc.
We’re going to test the following C# code.
public interface IWeapon{
int Attack(IWarrior warrior);
int Damage();
}
public interface IWarrior
{
int Id { get; }
string Name { get; set; }
bool IsKilledBy(IWeapon weapon);
int Attack(IWarrior target, IWeapon weapon);
int SurviveAttackWith(IWeapon weapon);
}
public class Sword : IWeapon
{
public int Attack(IWarrior warrior){
return warrior.SurviveAttackWith(this);
}
public int Damage(){
return 4;
}
}
I generally create a bacon_helper.rb file where I group my requires and helper functions etc. In the case of this test I have the following in the bacon_helper.rb:
# add some search paths to ironruby
# this first one adds the path with the assemblies
# this enables us not to have to specify a path to the assemblies everywhere.
$: << File.dirname(__FILE__) + "/bin"
# adds the path to the caricature library.
$: << File.dirname(__FILE__) + "/../lib"
# load the caricature library
require "caricature"
require 'caricature/clr'
# load the bacon library
require 'bacon'
# Add the .NET framework
require 'mscorlib'
# load the assembly with the C# code
load_assembly 'ClrModels'
At this point we’re ready to start writing the test. create a file called sword_spec.rb and we’ll add the following content to the file.
require File.dirname(__FILE__) + "/bacon_helper.rb"
describe "ClrModels::Sword" do
before do
@warrior = Caricature::Isolation.for ClrModels::IWarrior
end
it "should call survive_attack on the mock" do
@warrior.when_receiving(:survive_attack_with).return(5)
sword = ClrModels::Sword.new
sword.attack(@warrior).should.equal 5
@warrior.did_receive?(:survive_attack_with).should.be.successful
end
it "should return different results when expectation is defined with arguments" do
sword1 = ClrModels::Sword.new
sword2 = ClrModels::Sword.new
@warrior.when_receiving(:survive_attack_with).return(5)
@warrior.when_receiving(:survive_attack_with).with(sword2).return(15)
sword1.attack(@warrior).should.equal 5
sword2.attack(@warrior).should.equal 15
@warrior.did_receive?(:survive_attack_with).with(sword2).should.be.successful
end
end
So now we’ve got 2 tests for our Sword class. The only thing that is left to do is to run the specs. You can do that by executing the ibacon command and passing it the file you want to test.
+ C:\dev\caricature
(master) » ibacon spec/sword_spec.rb
ClrModels::Sword
- should call survive_attack on the mock
- should return different results when expectation is defined with arguments
2 specifications (5 requirements), 0 failures, 0 errors