JonathanGailliez
JonathanGailliez

Reputation: 1627

Objective-C NSArray, Block, STAssertEquals

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

Answers (2)

Mark Bernstein
Mark Bernstein

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

wattson12
wattson12

Reputation: 11174

I think STAssertEquals expects 2 objects, you should do something like

STAssertTrue([myArray count] == expectedCount, @"Count is wrong);

Upvotes: 0

Related Questions