Archive for October, 2008

Agile Development Practices teaser podcast

I’ll be giving a keynote at Agile Development Practices. Joey McAllister of SQE interviewed me about it. The focus is on what’s missing from the Agile Manifesto. I think of the Manifesto as a contract proposal from a development team to the business. They offer to not surprise the business, deliver working software frequently, and not whine about requirements. In return, the business has to not “help” them with process, tools, and estimates. And it has to commit to a lot of communication.

In the beginning, that was a hard sell, but it’s not any more. Agile is a safe-enough choice. Now teams need to execute on their promise. To execute, they need values that apply within the team, not just across the team-business boundary. In my talk, I’ll describe those values. They’re a superset of the ones I described at XP Day Toronto.

FlexMock and RubyCocoa

Because FlexMock and RubyCocoa disagree about the use of method_missing, you need to use flexmock as follows:

flexmock(SomeSubclassOfNSObject)

If the method you want to mock isn’t already defined on SomeSubclassOfNSObject, you have to define it before mocking it:

class Watcher <  OSX::NSObject
  def observeValueForKeyPath_ofObject_change_context(
             keyPath, object, change, context)
  end
end

That is ugly and horrible, so I wrote some code to make the class for me. It’s called rubycocoa_flexmock. It’s used like the following. (I use Shoulda, plus I add some syntactic sugar of my own to FlexMock).

  CALLBACK=:observeValueForKeyPath_ofObject_change_context

  context change callbacks do
    setup do
      @watcher = rubycocoa_flexmock(CALLBACK, 4)       # DEFINITION
      @observed = ObservableValueHolder2.alloc.initWithValue(’original‘)
    end

    should include the keypath and changed object do
      add_observer(:watcher => @watcher, :forKeyPath => value‘)   

      during {
        @observed.value = hello
      }.behold! {
        @watcher.should_receive(CALLBACK).once.    # USE
                 with(’value‘, @observed, any, any)
      }

    end
  end

rubycocoa_flexmock can take multiple name/argcount pairs. It’s annoying that you have to give it that information. The problem is that the dependence on an existing method happens within should_receive, but the number of arguments is only known in the following with message. And if you never give it a with, the number of arguments is never known. RubyCocoa is picky about Ruby argument declarations matching exactly what it knows from Objective-C, and I haven’t found a way around that.

The declaration of rubycocoa_flexmock is here. Not the greatest code I’ve ever written, but ’twill serve, ’twill serve.