FlexMock, RubyCocoa, and Notifications
I was using FlexMock to test code using Cocoa NSNotifications. I discovered an odd thing, which might be useful to someone doing a Google search some day.
My setup code originally looked like this:
def setup @observed = NSObject.alloc.init @watcher = flexmock(NSObject.alloc.init) end
The notification connection was set up like this:
center = NSNotificationCenter.defaultCenter center.addObserver_selector_name_object(@watcher, :posted, "name", @observed)
That didn’t work. FlexMock recorded no calls to posted
. I discovered that it worked if FlexMock were given a descendent of NSObject instead of an NSObject itself:
def setup @observed = NSObject.alloc.init @watcher = flexmock(SomeRandomWatcher.alloc.init) end
SomeRandomWatcher is a pretty simple class…
# Use this class when creating a mock that’s to receive a notification. # I don’t know why you can’t use NSObject, but you can’t — the notification # will not be received. class SomeRandomWatcher < OSX::NSObject end
You can find the rest of the code here: mock-example-notifications.rb. I have an idiosyncratic style for writing mocking tests. Explanation of the syntax I use is here.
You can run the example if, at some point in the past, you’ve installed these gems:
$ sudo gem install Shoulda $ sudo gem install flexmock