2013-11-27 34 views
0

當測試從故事板中加載的UITableViewController子類時,cellForRowAtIndexPath將返回零,除非我:A)發送它viewWillAppear:YES或B)獲取tableView.numberOfSections。爲什麼我必須調用viewWillAppear來獲取cellForRowAtIndexPath?

這是爲什麼?爲什麼不訪問視圖或發送主線程上的loadView選擇器來完成這項工作?

SpecBegin(CustomerViewController) 
    describe(@"CustomerViewController", ^{ 

    __block CustomerViewController *_vc; 

    beforeEach(^{ 
     NSLog(@"Before Each"); 
     UIStoryboard *mainstoryboard = [UIStoryboard storyboardWithName:@"Storyboard_Pad" bundle:nil]; 
     _vc = (CustomerViewController *)[mainstoryboard  instantiateViewControllerWithIdentifier:@"customer"]; 
    }); 

    it(@"the first cell should be the fullName cell", ^{ 
     // Following line is needed to make the following tests pass. 
     [_vc viewWillAppear:YES]; 
     UITableViewCell *cell = [_vc.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 
     expect(cell.reuseIdentifier).to.equal(@"fullName"); 
    }); 

    }); 

SpecEnd 
+1

是什麼在你viewWillAppear中的方法?該方法是否可以設置表視圖的數據源? –

+0

我甚至不確定你發佈的代碼的含義。什麼是「describe」,「it」和「expect」的函數?他們在做什麼? – Macondo2Seattle

+2

@BlackRider他正在嘗試單元測試UI。瑞恩,我強烈建議測試你的模型,而不是消耗它的UI。 –

回答

0

所以事實證明,使用視圖控制器的方法工作,但不是直接在表視圖對象的方法。當您通過視圖控制器執行操作時,不需要撥打viewWillAppear

這工作:

[_vc tableView:_vc.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 

這不

[_vc.tableView cellForRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 
+0

那麼爲什麼不從控制器中解耦你的UITableViewDataSource呢? –

+0

@ErikKerber是的,這似乎是下一個合乎邏輯的步驟。 –

1

看起來你是單元測試UI代碼。我通常會建議不要這樣做,因爲您將手動嘗試模擬ViewController生命週期方法,以便接近以重現您的UI在正在運行的應用程序中的行爲方式。

我建議嘗試兩件事情,而不是:

  1. 單元測試你的模型/邏輯(如,數據表格視圖消耗)。
  2. 如果你必須測試你的用戶界面,我建議用Xcode來查看Automated Testing
+0

你是對的,如果我要測試用戶界面,我會更好地使用UIAutomation或Calabash服務。我正在做的是測試我從我寫的一堂課的方法中得到正確的回報。事實證明,正確的做法是通過控制器,正如您在下面的答案中所看到的。 –

相關問題