From: Aaron V. <gru...@gm...> - 2008-07-24 00:03:19
|
Hi all, I'm not to reading this list, so hopefully this isn't already a well-known fact, but I wanted to share a trick that I spent a few brain cells discovering: I've been using Dr. Nic's rbiphonetest < http://drnicwilliams.com/2008/07/04/unit-testing-iphone-apps-with-ruby-rbiphonetest/ > to write rspec specs and stories for an obj-c cocoa app. I came across two problems when trying to use mock objects to test obj-c classes. 1) aMock = mock("a"); aMock.stub!(:methodThatReturnsInt).and_return(42); In this case (and I don't claim to understand what's behind the scenes), the 42 gets cast incorrectly when it's passed off to obj-c, since rubycocoa thinks it's returning an object instead of an int. The solution: class MockA < OSX::NSObject objc_method :methodThatReturnsInt, "i@:" end aMock = mock("a"); aMock.stub!(:methodThatReturnsInt).and_return(42); 2) aMock = mock("a"); # This is a mock of an obj-c class, OSX::A aMock.stub!(:methodThatReturnsInt).and_return(42); OSX::MyObjCClass.alloc.init.doSomethingWithA(aMock); This is only a problem if MyObjCClass has some logic in it that is checking [aMock isKindOfClass:[A class]]. But here's a way to work around it and make a Spec::Mocks object that obj-c thinks is a subclass of MyObjCClass. The trick is to create a subclass of MyObjCClass and then reimplement all it's methods to call super.super.method so that the call will eventually get back to Spec::Mocks' monkey-patching and our stubs and should_receive's will work. class MockA < OSX::A def methodThatReturnsInt return super.super.methodThatReturnsInt end end aMock = mock("a"); aMock.stub!(:methodThatReturnsInt).and_return(42); OSX::MyObjCClass.alloc.init.doSomethingWithA(aMock); And now we can write specs for obj-c code that calls isKindOfClass: ! (Note that the previous objc_method trick is no longer necessary.) === That's all! I hope someone finds this interesting or useful. I'd also appreciate any alternative suggestions from those who have inner knowledge of rubycocoa or rspec. Cheers, --Aaron V. |