4

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, @"");
psobko
  • 1,548
  • 1
  • 14
  • 24

3 Answers3

4

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.

Rudolf Adamkovič
  • 31,030
  • 13
  • 103
  • 118
  • That's what I though, I tried a few more things but this seems to be the only solution. Thanks. – psobko Jan 24 '14 at 18:23
0

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];
        ...
}
Rami Enbashi
  • 3,526
  • 1
  • 19
  • 21
  • The problem is that I want to test what has been set in the storyboard, I tried the code added to the question but I'm not able to access any of the IBOutlets from the storyboard. – psobko Jan 15 '14 at 19:49
  • Yeah, my suggestion was to set all the IBOutlets in the custom cell problematically. Given the additional info in your modified question, if you want to re-use the cell from the storyboard then you just need to use `QRFeedAdCell *cell = [mockTableView dequeueReusableCellWithIdentifier:@"feedAdCell"];` without registering or instantiating the cell, if you are setting the same identifier value in the storyboard. – Rami Enbashi Jan 15 '14 at 23:15
  • Wasn't able to get it working this way. I think Rodulf is right, the only way I could get it working was to instantiate the storyboard. – psobko Jan 21 '14 at 16:30
0

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");
Jon
  • 555
  • 5
  • 5