I am trying to learn unit tests. Following is my first ever written unit test for comparing string returned from the server. I am sure it's not perfect the way I handled the internet connection's availability and nsnotification. Test testGetURLEncodedString always printed pass as there is no assert statement in it. I can't put assert there as I have to compare the returned result from the server after response is received. Could anyone please suggest me to correct way of doing this please.
#import "MyAppTests.h"
@interface MyAppTests()
@property(nonatomic) AppDelegate *delegate;
@end
@implementation MyAppTests
@synthesize delegate = _delegate;
- (void)setUp
{
[super setUp];
self.delegate = (AppDelegate *)[[UIApplication sharedApplication] delegate];
if(![self.delegate internetConnectionAvailable])
{
STFail(@"Internet is not reachable.");
exit(-1);
}
}
- (void)tearDown
{
_delegate = nil;
[super tearDown];
}
- (void)testDelegate
{
STAssertNotNil(self.delegate, @"Cannot find the application delegate");
}
- (void)testGetURLEncodedString
{
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getURLEncodedStringSuccess:) name:@"getURLEncodedStringSuccess" object:nil];
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(getURLEncodedStringFailed:) name:@"getURLEncodedStringFailed" object:nil];
[self.delegate getURLEncodedString:@"Testing Text"];
}
-(void)getURLEncodedStringSuccess:(NSNotification *)notification
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"getURLEncodedStringSuccess" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"getURLEncodedStringFailed" object:nil];
STAssertTrue([[self.delegate getURLEncodedStringResponse] isEqualToString:@"Testing Text"], @"testGetURLEncodedString failed - did not receive expected response");
}
-(void)getURLEncodedStringFailed:(NSNotification *)notification
{
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"getURLEncodedStringSuccess" object:nil];
[[NSNotificationCenter defaultCenter] removeObserver:self name:@"getURLEncodedStringFailed" object:nil];
STFail(@"testGetURLEncodedString failed - server failed returning result");
}
Automated tests that call a server and check the response are better called "acceptance tests" of the server. But they should be kept in a separate target from the an app's unit test target, because unit tests need to be blazingly fast. And the main way to keep them fast is to avoid any real networking. And that's getting a little advanced.
Since you're just getting started with OCUnit, I suggest you not start with acceptance tests, because they're typically harder to write and provide less precise feedback. Instead, begin with the simplest tests which are tests of your model logic. My Xcode TDD 101 may be helpful for learning the mechanics of unit testing.