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?