Thursday, May 08, 2008
In preparation for my upcoming Code Camp session on IronRuby I've been hacking around on the IronRuby source, as well as on Ruby programs that can run on IronRuby.  One of the core areas of interest for me concerning IronRuby is in writing specifications for my .NET applications using Ruby.  While I've been learning Ruby (the real kind) I've become very fond of the testing libraries they have available, most notably RSpec and mocha

Over the last two nights I've been writing some ruby code to test .NET classes written in C#.  With a few of the hacks I have locally, I've had some pretty good success.  The following set of specifications verify the behavior of an Account class I've written.

require "../../trunk/tests/ironruby/Util/simple_test.rb"
require "IronRubySamples"
include IronRubySamples

describe "Account" do
    describe "When depositing money into my account" do
        it "should increase my balance by the amount deposited" do
            account = Account.new(10)
            account.Deposit(10)
            account.Balance.should == 20
        end
    end
                               
    describe "When withdrawing money from my account" do
        it "should decrease my balance by the amount withdrawn" do
            account = Account.new(100)
            account.Withdraw(50)
            account.Balance.should == 50
        end
    end
                   
    describe "When withdrawing money from an account with insufficient funds" do
        it "should tell me I have insufficient funds" do
            account = Account.new(30)
            should_raise(InsufficentFundsException) { account.Withdraw(50) }
        end
    end
   
    describe "When making a withdraw that drops my balance below the minimum" do
        it "should reduce my account by the amount withdrawn + the low funds charge amount" do
            account = Account.new(55)
            account.Withdraw(50)
            account.Balance.should == 4
        end
    end
end

The next step in my quest to test .NET code with IronRuby required me to figure out how to mock out dependent objects.  I considered several different options.  My first thought was to try and use "simple mock", however, I quickly realized via Scott Bellware that while it worked well on IronRuby libraries it wouldn't fit my needs.  My next thought was to give Moq a try.  After downloading Moq, I attempted to run a spec that referenced Moq and created a Mock<T> instance as shown below:

require "../../trunk/tests/ironruby/Util/simple_test.rb"
require "IronRubySamples"
require "Moq"
include Moq
include IronRubySamples

describe "LoginController" do
    describe "When a user logs in" do
        it "should vallidate credentials with login service" do
            mock = Mock.of(ILoginService).new
            #do expects
           
            controller = LoginController.new(mock.Object)
            controller.Login("steve", "****")
        end
    end
end

When running this via ir.exe I got an error that "Moq.Mock is not a generic type".  After poking around a bit I discovered this was due to a bug in IronRuby.  Currently IronRuby has problems when there is a generic and non generic type of the same name within a referenced assembly.  In order to work around this, I first tried to figure out what needed to be modified in IronRuby, however, that wasn't very fruitful so I decided to modify the source for Moq to get around my problem.  After renaming the static Mock class in Moq to MockRetriever, and hacking around another bug in IronRuby related to creating generic types where the type argument is an interface, I was finally able to get IronRuby to create the Mock<ILoginService> type:

mock = Mock.of(ILoginService).new

Unfortunately, this led to me to another roadblock.  When setting up expectations in Moq you do so with lambda expressions such as:

// C#
var mock = new Mock<ILoginService>();
mock.Expect(s => s.Login("steve", "****"));

While IronRuby has blocks and lambda's it doesn't have a way to express the above (at least that I know).  I'm going to dig around in the IronRuby source a bit to see if any ideas pop into my head, but at this point I'm not very hopeful. 

Friday, May 09, 2008 1:09:46 AM (Eastern Daylight Time, UTC-04:00) | Comments [3] |  |  | #
Tracked by:
"Link Listing - May 8, 2008" (Christopher Steen) [Trackback]
"Link Listing - May 8, 2008" (Christopher Steen) [Trackback]
"Beats Programming Timbaland Style Javascript Tutorial J2ee" (Beats Programming ... [Trackback]
Search
Archive
Links
Categories
Admin Login
Sign In
Blogroll
Themes
Pick a theme: