Question

I'm using a combination of XCTest and OCMock for testing an iOS application. I'm using a UITableViewController to present a series of prototype cells which I would like to write some tests for. The cell itself is in a storyboard so I don't believe I can instantiate it from a nib.

Is the only option to use the viewController which uses the cell to instantiate it?

The custom cell class I'm using has a number of 'IBOutlets' connected to the prototype on the storyboard. The cell class looks something like this:

@interface QRFeedAdCell : UITableViewCell

@property (strong, nonatomic) IBOutlet UIImageView *mainImageView;
@property (strong, nonatomic) IBOutlet UIImageView *blurredImageView;
@property (strong, nonatomic) IBOutlet UILabel *titleLabel;
@property (strong, nonatomic) IBOutlet UIButton *someButton;
@property (strong, nonatomic) IBOutlet UILabel *someLabel;
@property (strong, nonatomic) IBOutlet UILabel *anotherLabel;
@property (nonatomic) BOOL isBusy;

@end

I've tried instantiating the cell using [[QRFeedAdCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"feedAdCell"]; but that will load the cell with all of the properties set to nil.

I've also tried registering the cell, but the tests also fail:

 id mockTableView = [OCMockObject niceMockForClass:[UITableView class]];
[mockTableView registerClass:[QRFeedAdCell class] forCellReuseIdentifier:@"feedAdCell"];

QRFeedAdCell *cell = [mockTableView dequeueReusableCellWithIdentifier:@"feedAdCell"];

XCTAssertNotNil(cell, @"");
XCTAssertNotNil(cell.mainImageView, @"");
Was it helpful?

Solution

You can't.

The only way to test it is to instantiate the storyboard, then the view controller, then the cell itself, and then test the properties you set in the Interface Builder.

OTHER TIPS

You can instantiate programmatically but first you need to register it by calling

[self.tableView registerClass:[UITableViewCell class] forCellReuseIdentifier:@"cellId"];

Then you can do custom styling to the cell or whatever you usually do in the storyboard like this

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cellId" forIndexPath:indexPath];

        // create and add a label
        UILabel * label = [[UILabel alloc]initWithFrame:CGRectMake(10, 8, 155, 21)];
        label.text = @"text";
        [cell addSubview:label];
        ...
}

This is working for me in a basic way. I havent gotten viewwillappear to run yet tho.
ViewdidLoad runs when you call .view on _vc.

@property (nonatomic, strong) Edit_ProfileVC *vc;
@property (nonatomic, strong) UIView *view;
@property (nonatomic) NSMutableDictionary *params;

 UIStoryboard *mainSB = [UIStoryboard storyboardWithName:@"MainStoryboard" bundle:nil];
    _vc = [mainSB instantiateViewControllerWithIdentifier:@"EditProfileVC"];
    _vc.userData = [[EditUserTableDataSource alloc] initDataSourceWithJSON:self.params];
    _view = _vc.view;
    XCTAssertNotNil(_view, @"the view is not loading properly");
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top