3

How to write a testcase for this "success" scenario?

if ([tblView.delegate respondsToSelector:@selector(tableView:viewForHeaderInSection:)]) {
         ...
}else{
         ...
}

I have tried by creating the below mock delegate in swift:

class MockTableViewDelegate:NSObject, UITableViewDelegate {

  @objc func tableView(tableView: UITableView, heightForHeaderInSection section: Int) -> CGFloat {
            return 30
        }

        // MARK: Delegates
   @objc func tableView(tableView: UITableView, viewForHeaderInSection section: Int) -> UIView? {
            return UIView()
        }
}

Code:

mockTableView.delegate=MockTableViewDelegate()  
print("delegate===\(mockTableView.delegate)")

It prints nil. The same mockup I have tried for the datasource and it is returning the datasource obj. Why delegate is returning nil? and how to test this scenario?

Satheesh
  • 10,998
  • 6
  • 50
  • 93
SaRaVaNaN DM
  • 4,390
  • 4
  • 22
  • 30
  • Is `tblView.delegate` non nil in the if? If non-nil, is its type `MockTableViewDelegate`? – Lou Franco May 03 '16 at 13:45
  • is the tblView's delegate property set via Storyboard or Code? The time and context play important role in the delegate and datasource properties. At what point is the test case run? – Satheesh May 10 '16 at 09:15

2 Answers2

1

Delegates are usually weak references. If you assign your MockTableViewDelegate to a local variable first it should still be alive when used in print. Try the following:

let delegate = MockTableViewDelegate()
mockTableView.delegate = delegate
print("delegate===\(mockTableView.delegate)")
print(delegate)

The fourth line is required to keep the object living for the third line.

0x52
  • 91
  • 7
  • Tried no luck. I think this is same as what i have posted. – SaRaVaNaN DM May 04 '16 at 03:58
  • what is the type of mockTableView? If it's not UITableView, then have you done something to the delegate property? – Lou Franco May 04 '16 at 13:51
  • This might also not hold the weak reference because you aren't using delegate either. Add `print("delegate===\(delegate)")` to the bottom. If that works, add a delegate member property to the test case. – Lou Franco May 04 '16 at 13:52
  • @LouFranco is right. If you don't use `delegate` after the third line it might get deallocated after the second line. Please see my updated answer. – 0x52 May 04 '16 at 20:25
  • I guess its swift issue. because i tried the same for datasource and its working. eg:1. let delegate = MockTableViewDelegate() 2. mockTableView.delegate = delegate 3. mockTableView.datasource = delegate. – SaRaVaNaN DM May 06 '16 at 05:38
0

Finally i found this is a bug in the iOS runtime. The one way to solve this problem is to use OCMock, but its not available for Swift. So I have written in Objective-c for now.

UITableView *tableView = [[UITableView alloc]init];
UIView *headerView = [UIView new];

id delegateProtocolMock = OCMProtocolMock(@protocol(UITableViewDelegate));
tableView.delegate=delegateProtocolMock;
OCMStub([delegateProtocolMock tableView:tableView viewForHeaderInSection:0]).andReturn(headerView);
SaRaVaNaN DM
  • 4,390
  • 4
  • 22
  • 30