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

Leave a Reply

You must be logged in to post a comment.