tags:

views:

184

answers:

2

I'm looking for some style advice for testing this piece of (Objective-)C++ code, I bracketed the Objective part, as I don't think it should have any bearing on this test.

class Probe
{
  public:
    bool playing();
}

bool Probe::playing()
{
  NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
  iTunesApplication *iTunes = [SBApplication applicationWithBundleIdentifier:@"com.apple.iTunes"];

  // Logic here to determine if iTunes is playing requires a running iTunes.
  // The behavior can also differ depending if iTunes is playing a DVD, CD, 
  // Stream, a File, something from the iTunes store, and a bunch of other factors

  [pool release];
  return 1;
}

As alluded to in the code, the behavior of this method is hung on an upstream environmental detail that I can't rely upon when running tests (which I haven't started to write yet.)

How should one effectively test for these conditions, where you rely on a scripting bridge, or a com adapter, or an upstream API. For example, I want to make sure that another method print_whats_playing() prints nothing, if nothing is playing, or that some other condition is met, in a sane way.

There's a second argument to this, which is to isolate (rather than for convenience) my test suite from actually needing to hit these system services, or APIs, perhaps the machine building is firewalled, and can't reach an API, or some other condition. Especially in this case, how to ensure that an API call (network, or local) fails so you can properly test an error condition in your code?

In my home (Ruby-land) you would "stub" (see http://martinfowler.com/articles/mocksArentStubs.html ) or "mock" the role, which in Ruby is easy, because you can simply redefine a test class.

Also, in individual test cases, you can short-circuit methods, by something like probe.expects(:playing).once.returns(false) - naturally it's not going to be that easy in C++, but maybe there's something on the way I can enjoy?

A: 

So, I found my solution, after stumbling upon a remarkably well endowed list at wikipedia of C++ testing frameworks, I stumbled upon GoogleTest and the Google C++ Mocking Framework. Which fulfills all my requirements, whilst it's a little trickier to use than the Ruby counterparts, it is equally well featured.

One thing I'm not so happy, or certain about is stubbing system calls - it looks as though I would have to wrap them in my own class which I can then mock responses on - I don't have a strong feeling either way about this, but it doesn't feel optimal, although does allow me to be clear about what pieces of system functionality are relied upon.

Beaks
+1  A: 

If you're still looking for a true Mocking framework in C++ you should check Isolator++ from Typemock. It can mock any call in C++, the only downside from your perspective that it currently only work in windows.

Dror Helper
@Dror - thanks, that's a useful tip - regrettably my library is cross-platform but it's a bookmark for next time this comes up - maybe they mature and can run on Lin/BSD too. Thanks Dror.
Beaks