OCMock Woes


So I’m building and running tests and banging my head against oncoming traffic while trying to get the OCMock framework to do something… I dunno… mocky? I’m running Xcode 4.2 build (4D199) on Lion. Dragging and dropping the freshly downloaded “.framework” bundle doesn’t want to link. Hi, I’m Cliff and you’re here because you have linker errors in your XC4 project while trying to get objects to pretend to be other objects. I’m here to try to help you work through some of the issues.

So I try building the static lib and forcing it. The first roadblock I hit was with the ${BUILD_STYLE} environment no longer being set. ${BUILD_STYLE} is changed to ${CONFIGURATION} in Xcode 4. The second bump I hit was with categories not loading from the static lib I generated. Setting “-ObjC” under “Other Linker Flags” solved this. Next I get OCMock to load but auto complete doesn’t work with the category methods added to “id”. (Eg. stub, expect, verify, etc.) I accidentally set my “Header Search Path” incorrectly. You have to set it to point to the folder that contains the OCMock folder with the header files in it, then you can successfully import in your test cases. Finally auto-complete works and things load but setting simple expectations on a mocked string appears to be broken. I’m now wondering if I should download source from the git repo instead of building the source included in the dmg. It’s late and I’m incredibly frustrated with not being able to write a single test all day…

You must fail before you can succeed!


If you try to fail and you succeed, which have you actually done? Are you a success? Or a failure? Is it good to be a failure? Is it better to be successful at failure? Let’s add detail to the question. By the way, I’m Cliff. You’re here because you tried to fail and you succeeded. Today’s topic is something I’ve visited before. It’s a new thing I’m trying with unit tests. Actually it’s an old thing to many but I’m trying it for the first time in both C++ and ObjC so it feels sorta new-ish.

How do you unit test?
Let’s start with how you unit test. What are your steps? What are the recommended steps? In order to be successful at TDD you must appreciate the entirety of the practice. It goes, “Red, Green, Refactor”. Red comes before Green, just like with traffic lights. What I’m saying is that you have to begin with a failing test. The first test is important. The first failure should describe what work you have to do. In my case, I’m swimming in un-ventured waters (C++/ObjC++ testing) so there’s some learning that needs to be re-enforced. Here’s how I’ve been starting my tests recently:

//
//  MyCoolNewObjectTest.m
//  Created by cliftoncraig07 on 12/1/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import <SenTestingKit/SenTestingKit.h>
#include "MyCoolNewObject.h"

@interface MyCoolNewObjectTest : SenTestCase
{
  MyCoolNewObject *coolObject;
}
@end

@implementation MyCoolNewObjectTest

-(void) setUp
{}

@end

The test shell is completely empty except for references to the “thing” I’m about to create. I get my first failure which is a compile error stating that this thing does not exist. “No such file error…” around the include. Here I have an opportunity to review my design as minimalist as it is. I ask, “Does the error make sense? Is it expected? Do I like the name of this cool new thing I’m creating? Is it specific to the task I’m assigned to?” Always review each error with these question. After creating the files for the new “thing” I then follow up with:

//
//  MyCoolNewObjectTest.m
//  Created by cliftoncraig07 on 12/1/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import <SenTestingKit/SenTestingKit.h>
#include "MyCoolNewObject.h"

@interface MyCoolNewObjectTest : SenTestCase
{
  MyCoolNewObject *coolObject;
}
@end

@implementation MyCoolNewObjectTest

-(void) setUp
{ STFail(@"You must fail before you can succeed!"); }

@end

Also important, while I train myself on the new testing framework, because I need to catch myself misnaming the “setup” method which should have a capital “U”. It also lets me know that my test is actually running as part of the suite. Far too often, in Xcode, I’ll have the wrong target active and begin writing the wrong code because I was getting false positives from tests that were never run. Here’s where it gets interesting. The STFail in the above example does not fail! Now we face our original question, if you try to fail, as we have above, and you succeed like our test suite will do here, which have you actually done? The first time I hit the unexpected success I got nervous and read all around the SenTesting framework and OCUnit. Eventually I settled on the conclusion that because there were no tests to run the setUp was being optimized away as unnecessary. What the above example is pointing out is that such a test case can never fail since there are no tests. That leads us to our final step…

//
//  MyCoolNewObjectTest.m
//  Created by cliftoncraig07 on 12/1/09.
//  Copyright 2009 __MyCompanyName__. All rights reserved.
//
#import <SenTestingKit/SenTestingKit.h>
#include "MyCoolNewObject.h"

@interface MyCoolNewObjectTest : SenTestCase
{
  MyCoolNewObject *coolObject;
}
@end

@implementation MyCoolNewObjectTest

-(void) setUp
{ STFail(@"You must fail before you can succeed!"); }

-(void) testSomething
{}

@end

…and here we get our familiar red bar! Our test case is complete and we now understand a little more about OCUnit. That’s it for today. Go on. Nothing else to see here. I know what you’re thinking. “We haven’t written or learned anything new!” Sure we have! We’ve written and validated our first test case in ObjC++. (I’m using OCUnit w/ C++ extensions to exercise or test drive C++ code.) The little amount we went over here is persistent through all the testing you will do from then on. It starts from the basic mechanics. Make sure every line of code is proceeded by some test (or compiler) failure. If you’ve done more than 2-3 things and haven’t run a build to generate a failure then you’re completely off track.

Hard to test things


So I’d been thinking. Because I’m back into iPhone development and getting warmed up not only to ObjC issues and errors but also C++ oddities, I’m wondering how do you write tests for some of the more difficult things to capture? For instance, I’ve figured out how to capture some of the manual reference counting that’s required by CocoaTouch. (I assert that objects passed into other objects are properly retained and properly released when the object itself is released.) Still I can’t capture the more involved memory management problems. How do you assert an autorelease? What about dynamic memory allocation with pointers? I ended up with a single method that dynamically allocates for a pointer via malloc. I then changed it to use new with array notation.

void MySpecialObject::writeRequestToStream(CFStringRef aRequest, CFWriteStreamRef requestStream)
{
if(CFWriteStreamGetStatus(requestStream) == kCFStreamStatusNotOpen) CFWriteStreamOpen(requestStream);
UInt8* convertedString =(UInt8*)convertToCString(aRequest);
CFWriteStreamWrite(requestStream, convertedString, CFStringGetLength(aRequest));
free(convertedString);
}

It’s used in one spot so far and I’ve manually added the free without a prior failing test. I felt dirty. Assuming there were no call to free, how would you write a failing test for the code above? Is this just one of those things where you have to be extra careful? Maybe I should investigate the use of Velocity style code macros/templates that expand after keying special abbreviation similar to what we have in IntelliJ. I can imagine something like “cstr” expanding to:

char *myCStr = new char[size];
// use myCStr here
free(myCStr);

With the ability to tab through highlighting the variable name, declared size and commented insert code section. Any bright ideas?

AssertRunsInAnotherThread ?


**Update**
I’ve updated my example below after realizing I left out some important pieces…
**Update**

How do you assert that something runs in a different thread? Or more generically, how do you assert that something runs asynchronously? I need to do this in ObjC but also in Java. The scenario is as follows. I have a WhatzItz object instance stored in myWhatzItz. I tell myWhatzItz to doDisThing. I need to specify that myWhatzItz will doDisThing asynchronously. Experience tells the story that multi-threaded unit tests are dumb, complicated and wrong. So asking myWhatzItz to doDisThing then waiting or polling for completion of doDisThing is not what we want to do here. (It may be what you want to do but it’s not what I want. Since we’re on the same team and since I’m doing the writing you have to want what I want not what you want. I want you to want my wants… forget your wants… your wants are dumb anyhow!)

So how do we design myWhatzItz to doDisThing and doDisThing right? I’m going to suggest an interface… err prototcol. That is an abstraction for what we want to design. In unit testing we stay focused on one thing. All distractions are tossed behind abstractions. So after asking myWhatzItz to doDisThing I need to assert that it uses asynchronous behavior. That brings us a step back. I have to design a dependency on asynchronous behavior first. Right now you’re probably wondering how asynchronous behavior works. Right now I’m ’bout to slap you like Bruce Lee slapped that boy in Enter the Dragon. (Or was that Return of the Dragon? Maybe it was the game of death? Bonus points to the 1st person that gets the movie correct with a link to the clip on YouTube!) “Don’t focus on the finger or you’ll miss the beauty in the sky above!”, says Bruce. We don’t care about how asynchronous behavior works, as its irrelevant to our design. We only care that our work is done asynchronously! So we’ll code this test in ObjectiveC:

#import
@protocol MyAsynchronousBehavior
-(void) performAsynchronously:(SEL) aSelctor onTarget:(id)aTarget withObject:(id)anObject;
@end

@interface MyWhatzItzTest : SenTestCase <MyAsynchronousBehavior>
{
  MyWhatzItz *myWhatzItz;
  SEL selectorPerformed;
  id targetForSelector;
  id parameterForSelector;
  int performAsynchronouslyInvocationCount;
}
@end

@implementation MyWhatzItzTest

-(void) setUp
{
   myWhatzItz = [[MyWhatzItz alloc] init];
   //The test uses the self-shunt pattern to listen for MyAsynchronousBehavior interaction.
   id theAsynchronousBehavior = self;
   myWhatzItz.asynchronousBehavior = theAsynchronousBehavior;
}

-(void) testMyWhatzItzWillAsynchronouslyDoDisThingWhenAskedToDoDatThing
{
  STAssertEquals(performAsynchronouslyInvocationCount, 0, @"Assuming that we haven't been asked to performAsynchronously");
  [myWhatzItz doDatThing];
  STAssertEquals(performAsynchronouslyInvocationCount, 1, @"We SHOULD HAVE been asked to performAsynchronously");
  STAssertEquals(selectorPerformed, @selector(doDisThing:), @"Should have asked to doDisThing using asynchronous behavior.");
  STAssertEquals(targetForSelector, myWhatzItz, @"Should use myWhatzItz for asynchronous execution.");
}
@end
#pragma mark MyAsynchronousBehavior protocol methods
-(void) performAsynchronously:(SEL) aSelctor onTarget:(id)aTarget withObject:(id)anObject
{
  performAsynchronouslyInvocationCount++; selectorPerformed = aSelctor; targetForSelector = aTarget; parameterForSelector = anObject;
}

Supplying the asynchronous behavior becomes a construction/intialization concern, which could be extracted into a wiring framework like Interface Builder (or if you do Java, Springframework). The nice thing is that we can alternate our asynchronous behavior without touching the rest of the project. We can do something quick/dirty like detachThread… and later get more elegant with RunLoops. Today’s tip comes to you (me) completely by accident. I’ve been trying to test drive things in Java and ObjC for several years now and I’ve never got this part quite right. Feel free to share your opinions/experiences with threads and tests.

**Update**
The above example demonstrates a few important unit testing concepts. first it uses the self-shunt pattern to allow the test to become a mock and listen for interactions between the tested object and its collaborator(s). Second, it demonstrates the importance of using tests to carve out the pieces that should NOT be under test. In this situation it’s multi-tasking, however in other scenarios it could be anything from a DBMS to a network call. I could have illustrated an example where I spin up a Thread pool of some sort from within the test started work, paused the main thread and waited for a response. That’s what I’ve done in the past and it becomes extremely complicated and brittle. In stead, I use the elegance of abstraction to make the test 100% predictable, 200% more simplistic, and 300% more maintainable. Where do I get those statistics? The short answer is they’re sequential. (The long story begins yesterday when my 5yr old spontaneously decided to count from 1 to infinity in the middle of our shopping trip. You see, she only recently learned her numbers up to 100 and after getting to 199 we all realized the child’s computational limits as she continued with one hundred one hundred then followed up with one hundred one hundred one, one hundred one hundred two…)
**Update**

RSpec 4 iPhone BDD?


Is anybody doing this yet? I made an effort to use RSpec for iPhone development almost a year ago but got stumped on Ruby mock objects that didn’t seem to to play nice with CocoaTouch objects. I got a lot closer than my blog post would lead you to believe but stopped due to deadlines, and my lack of experience with both Ruby and ObjC. Tonight I dug up the old project and tried to remember where I left off…

…Aahh it’s al coming back to me now! I had wrapped the MockObject support in Ruby to ensure it received parameters from CocoaTouch. For some silly reason parameters passed directly from CocoaTouch objects are dropped/ignored by whatever mock framework Ruby is using with RSpec. Forgive me for not knowing more about the internals but I don’t do Ruby and this was from last November. Here’s an example of the RSpec I modified to allow parameters to pass cleanly. It also has the buddings of a dynamic message dispatch thingy I couldn’t get working because it makes no sense to hard code every anticipated method invocation. If one of you Ruby guys could jump in and patch this up or if somebody could point me to an already viable alternative that’d be so swell…


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')
    @bowling.stub!(:roll)
    @controller.bowling = ObjCMock.new(@bowling)
    @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
    #This line wraps the mock with the class defined above
    @controller.bowling = ObjCMock.new(@bowling)
    #The following line will cause failure calling directly into the mock
#    @controller.bowling = @bowling
    @bowling.should_receive(:roll).with(10)

    @controller.roll
  end
  
  it "should have an outlet to the score" do
    @score = mock('Score')
    @controller.score = @score
  end

end
//
//  BowlingController.h
//  BowlingController
//
//  Created by FIXME on 2008-11-10.
//  Copyright 2008 FIXME. All rights reserved.
//

#import "BowlingController.h"
#import "BowlingProtocol.h"

@implementation BowlingController
@synthesize pins;
@synthesize bowling;
@synthesize score;

-(void) roll{
	int val = (int) [self.pins intValue];
	printf("Value is: %i", val);
	[self.bowling roll:val];
}

@end

// This initialization function gets called when we import the Ruby module.
// It doesn't need to do anything because the RubyCocoa bridge will do
// all the initialization work.
// The rbiphonetest test framework automatically generates bundles for 
// each objective-c class containing the following line. These
// can be used by your tests.
void Init_BowlingController() { }

TDD for iPhone development


I’m getting more familiar with the tools and technology surrounding iPhone development but I still face challenges daily. Hi, my name’s Cliff. You’re here because a random Yahoo/Google search or cross-link from another site pulled you in by your chin hairs. (In the case of women reading you’re here because you’re trying to figure out where you husband/significant other spends all of his spare time.) Bear with me as I try to make sense of the tedium involved in XCode unit testing.

Not yer Daddy’s cup o’ Java!
For score and several years of Java development has seasoned me similar to a rotisserie side of pork spinning slowly over an open hearth. As a flavored piece of pig, I’ve come to expect certain things… from my IDE… from advertised test tools… from any form of modern development. For one, I don’t expect a ton of over head associated with adding a new test. Consequently, copying the Google tools for mac files into each project that wants to be agile is becoming painful. I’ve also come to expect… no demand a certain ability to easily decouple. Running things in isolation is key to true unit tests, not requiring the stars to line up is crucial. I’ve also grown used to the CLASSPATH. For those that only deal in XCode, Ruby, or Cocoa the CLASSPATH is the bane of all Java development allowing one to easily gain and/or dismally lose runtime visibility of entire libraries of supporting logic. Today I’m having trouble getting Objective-C class implementations to be visible without individually adding them. While that’s not too bad I found a classpathy work-around while playing with another open source project a while ago. This other project was setup with individual modules which made me very happy since it smells of modular reuse. It’s main module contained all of the supporting logic and could be embedded or reused in any client application. Writing tests that exercised anything from the project became a simple matter of adding that main module as a dependency of the test target.

My Dilemma
Because I started a project sans knowledge of how to properly decouple I have a bunch of classes tied to the default application build target in XCode. I tried to add this target’s output as a dependency of my test target as I did with the other project. Since the output is an executable application I believe it’s causing things not to work as expected. If you have any idea of a work-around that doesn’t involve adding each file loaded by the test to be manually added to both the application and the the test target then speak up.

Retribution *Ahem* Reimbursement
I’ve asked people to do my work for me plenty times before and I’m not ashamed to do it again. As your reward for being a faithful reader of my blog and committing occasional insight to my struggles you can expect silent but honorable mention as I speak to others on behalf of your contribution. Followup posts on this site to highlight your involvement in any way will be edited, reworded, and/or deleted prior to clearing moderation. (In all reality, I sincerely appreciate all comments and feedback. I don’t actually steal credit unless you request that I do and at the end of the day we’re all working towards a common goal… Don’t take nothing you read here seriously… it’s just jokes!)