*Update*
By the way I unsuccessfully tried overriding the methods() method and almost went as far as overriding send on my mock wrapping ObjCMock class. My experience in MOP tells me that overriding send is likely rooted in trouble so I decided against it.
Yesterday’s Ruby drama ended with my finding a hack around the dropped parameters. If I was more familiar with Ruby, had more time to kill, or if it were Groovy instead then my solution would be much cleaner.
The problem:
Ruby Mocks under RSpec (have no idea if the problem persists in other Ruby scripting environments) do not receive parameters correctly from native Cocoa objects.
The hack:
Use a home-grown mock to intercept the parameter and pass along to the Ruby mock.
The code: (bowling_controller_spec.rb)
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)
@delegate.roll(num)
end
# def method_missing(m, *args)
# puts “Forwarding message”
# @delegate.send(m, args)
# end
def initialize(theMock)
@delegate = theMock
end
end
describe BowlingController do
before(:each) do
@controller = BowlingController.new
@bowling = mock(‘BowlingProtocol’)
@text_field = mock(‘Pins’)
@text_field.stub!(:intValue).and_return(10)
@controller.pins = @text_field
end
it “should roll a ball” do
@controller.roll
end
it “should roll a ball and get the value from the pins outlet” do
@text_field.should_receive(:intValue).and_return(0)
@controller.roll
end
it “should be an OSX::NSObject” do
@controller.is_a?(OSX::NSObject).should == true
end
it “should have an outlet to a bowling object” do
@controller.bowling = @bowling
end
it “should send the pin value to the bowling object” do
@controller.bowling = ObjCMock.new(@bowling)
# @controller.bowling = @bowling
@bowling.should_receive(:roll).with(NSNumber.numberWithInt(10))
@controller.roll
end
end
I left in the commented out method_missing magic that doesn’t work the way I’d expect it. Ideally I’d like to tuck this wrapping mock to the side without needing to define the specific signature I’m mocking. Ideally method_missing would give me the ability to answer any message. Alas, I get “does not reckognize selector” errors from NSProxy when I enable it. I have a feeling that NSProxy probably looks through the defined methods on it’s delegate and throws this error without 1st trying to invoke the method… effectively killing any dynamic magic ability from objects passed into Cocoa land. I also have a feeling that there are a few other holes in the proxy approach with Ruby/Cocoa. If anybody happens to know the details feel free to chime in.

What y’all think about me…