Reputation: 1627
I work on an application listing the current live game of a sport. The informations about the live game are fetched from a remote source using REST. The first request give a list of live game with their id and the corresponding arena id. I then have to fetch the arena names from their id. When all is complete I send back a NSArray containing a list of live game.
I found a weird comportment in my SenTestCase when testing my parsing method passing NSArray through block. In my test, I'm able to do a [myArray count]
and display it's result in a NSLog but when I do a STAssertEquals([myArray count], 1, @"Error description")
the test crash with a EXC_BAD_ACCESS.
Here is my code reduced to the minimum and where I remove all the network aspect:
#import <SenTestingKit/SenTestingKit.h>
@interface LiveGameTests : SenTestCase
@end
@interface LiveGame : NSObject
@property (nonatomic) id gameID;
@property (strong, nonatomic) NSString *arenaName;
@end
@implementation LiveGame
// Create a live game object from a dictionary (this dictionary is the response of a first request to a remote server)
+(LiveGame *)gameWithData:(NSDictionary *)dict
{
LiveGame *liveGame = [[LiveGame alloc] init];
liveGame.gameID = dict[@"game_id"];
return liveGame;
}
// Complete a live game data with the element of a dictionary (those data are actualy fetched from a remote server in a different request.)
+(void)fetchRemainingData:(NSArray *)liveGameList completion:(void(^)(void))completion
{
LiveGame *liveGame = liveGameList[0];
liveGame.arenaName = @"arenaName";
completion();
}
// Parse a NSArray of NSDictionaries representing live game
+(void)parseArrayOfDictionary:(NSArray *)arrayToParse success:(void(^)(NSArray *liveGameList))success
{
NSMutableArray *liveGameList = [NSMutableArray arrayWithCapacity:[arrayToParse count]];
// Iterate on all the NSDictionary of the NSArray and create live game from each NSDictionary
[arrayToParse enumerateObjectsUsingBlock:^(NSDictionary *obj, NSUInteger idx, BOOL *stop)
{
liveGameList[idx] = [LiveGame gameWithData:obj];
}];
[LiveGame fetchRemainingData:liveGameList completion:^
{
success(liveGameList);
}];
}
@end
@implementation LiveGameTests
-(void)testParseArrayOfDictionary
{
[LiveGame parseArrayOfDictionary: @[@{@"game_id": @1}]
success:^(NSArray *liveGameList)
{
// This line work fine and print: 2013-03-08 13:39:35.288 ShotClock[55177:c07] liveGameList count = 1
NSLog(@"liveGameList count = %d",[liveGameList count]);
// This crash the test on a EXC_BAD_ACCESS. What's wrong?
STAssertEquals([liveGameList count], 1, @"The list of game must contain one unique live game but contain %@",[liveGameList count]);
}];
}
@end
NSLog(@"liveGameList count = %d",[liveGameList count]); => This line work fine and print: 2013-03-08 13:39:35.288 ShotClock[55177:c07] liveGameList count = 1
STAssertEquals([liveGameList count], 1, @"The list of game must contain one unique live game but contain %@",[liveGameList count]); => This crash the test on a EXC_BAD_ACCESS. What's wrong?
Upvotes: 2
Views: 410
Reputation: 2080
Your application crashed because
STAssertEquals([liveGameList count], 1, @"The list of game must contain one unique live game but contain %@",[liveGameList count])
tries to apply the %@ formatter to the result of [liveGameList count]. But %@ expects an Objective C object, where [liveGameList count] is returning the scalar "1". The runtime converts that scalar to a pointer to 0x00000001 and tries to use the "object" it finds there. But that's not a valid pointer, and so the runtime raises an invalid address exception.
Upvotes: 1
Reputation: 11174
I think STAssertEquals expects 2 objects, you should do something like
STAssertTrue([myArray count] == expectedCount, @"Count is wrong);
Upvotes: 0