RSpec 4 iPhone BDD?

Is anybody doing this yet? I made an effort to use RSpec for iPhone development almost a year ago but got stumped on Ruby mock objects that didn’t seem to to play nice with CocoaTouch objects. I got a lot closer than my blog post would lead you to believe but stopped due to deadlines, and my lack of experience with both Ruby and ObjC. Tonight I dug up the old project and tried to remember where I left off…

…Aahh it’s al coming back to me now! I had wrapped the MockObject support in Ruby to ensure it received parameters from CocoaTouch. For some silly reason parameters passed directly from CocoaTouch objects are dropped/ignored by whatever mock framework Ruby is using with RSpec. Forgive me for not knowing more about the internals but I don’t do Ruby and this was from last November. Here’s an example of the RSpec I modified to allow parameters to pass cleanly. It also has the buddings of a dynamic message dispatch thingy I couldn’t get working because it makes no sense to hard code every anticipated method invocation. If one of you Ruby guys could jump in and patch this up or if somebody could point me to an already viable alternative that’d be so swell…

require File.dirname(__FILE__) + '/test_helper'

require "BowlingController.bundle"
OSX::ns_import :BowlingController
OSX::ns_import :BowlingProtocol
require 'delegate'

include OSX

class ObjCMock
  attr_accessor :delegate
  def roll(num)
  # def method_missing(m, *args)  
  #   puts "Forwarding message"
  #   @delegate.send(m, args)
  # end
  def initialize(theMock)
    @delegate = theMock

describe BowlingController do
  before(:each) do
    @controller =
    @bowling = mock('BowlingProtocol')
    @controller.bowling =
    @text_field = mock('Pins')
    @controller.pins = @text_field

  it "should roll a ball" do

  it "should roll a ball and get the value from the pins outlet" do

  it "should be an OSX::NSObject" do
    @controller.is_a?(OSX::NSObject).should == true

  it "should have an outlet to a bowling object" do
    @controller.bowling = @bowling

  it "should send the pin value to the bowling object" do
    #This line wraps the mock with the class defined above
    @controller.bowling =
    #The following line will cause failure calling directly into the mock
#    @controller.bowling = @bowling

  it "should have an outlet to the score" do
    @score = mock('Score')
    @controller.score = @score

//  BowlingController.h
//  BowlingController
//  Created by FIXME on 2008-11-10.
//  Copyright 2008 FIXME. All rights reserved.

#import "BowlingController.h"
#import "BowlingProtocol.h"

@implementation BowlingController
@synthesize pins;
@synthesize bowling;
@synthesize score;

-(void) roll{
	int val = (int) [self.pins intValue];
	printf("Value is: %i", val);
	[self.bowling roll:val];


// This initialization function gets called when we import the Ruby module.
// It doesn't need to do anything because the RubyCocoa bridge will do
// all the initialization work.
// The rbiphonetest test framework automatically generates bundles for 
// each objective-c class containing the following line. These
// can be used by your tests.
void Init_BowlingController() { }

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s