jeudi 25 juin 2015

UICollectionView Unit Test Bad Access on dequeueReusableCellWithReuseIdentifier

To summarize my problem I am trying to test a collection view's data source. I Initialize a view controller and call viewDidLoad() to initialize the components which initializes a custom class to use as a data source. This is the class that I am testing.

The program starts in a unit test here:

class BubbleViewManagerTest: XCTestCase {

var viewController : DashboardViewController = DashboardViewController()
//var bubbleViewManager : BubbleViewManager = BubbleViewManager()

override func setUp() {
    super.setUp()

    let storyboard = UIStoryboard(name: "Main", bundle: NSBundle(forClass: self.dynamicType))
    viewController = storyboard.instantiateViewControllerWithIdentifier("DashboardViewControllerId") as! DashboardViewController
    bubbleViewManager = viewController.bubbleViewManager
    viewController.loadView()
    viewController.viewDidLoad()
}

func testCellForItemAtIndexPath() {
    DataManager.singleton.dayActivities = []

    DataManager.singleton.addGoal(Period(name: "asdf", hour: 1, minute: 1, color: UIColor.blackColor(), priority: PeriodPriority.Low))

    var cell = bubbleViewManager.collectionView(viewController.bubbleView, cellForItemAtIndexPath: NSIndexPath(forRow: 0, inSection: 0)) as! BubbleCollectionViewCell

    XCTAssertEqual(cell.bounds.width, 45)
    XCTAssertEqual(cell.bounds.height, 45)
    XCTAssertNotNil(cell.bubbleView.period)

    DataManager.singleton.addGoal(Period(name: "asdf", hour: 1, minute: 1, color: UIColor.blackColor(), priority: PeriodPriority.Medium))
    DataManager.singleton.addGoal(Period(name: "asdf", hour: 1, minute: 1, color: UIColor.blackColor(), priority: PeriodPriority.High))

    var index = NSIndexPath(forRow: 1, inSection: 0)

    cell = bubbleViewManager.collectionView(viewController.bubbleView, cellForItemAtIndexPath: index) as! BubbleCollectionViewCell


    func collectionView(collectionView: UICollectionView, cellForItemAtIndexPath indexPath: NSIndexPath) -> UICollectionViewCell {

    let period: Period = DataManager.singleton.dayActivities[indexPath.row]
    var cell: BubbleCollectionViewCell = BubbleCollectionViewCell()

    switch period.priority {
        case .High:
            cell = collectionView.dequeueReusableCellWithReuseIdentifier(self.reuseIdentifierHighPriority, forIndexPath: indexPath) as! BubbleCollectionViewCell
            break;
        case .Medium:
            cell = collectionView.dequeueReusableCellWithReuseIdentifier(self.reuseIdentifierMediumPriority, forIndexPath: indexPath) as! BubbleCollectionViewCell
            break;
        case .Low:
            cell = collectionView.dequeueReusableCellWithReuseIdentifier(self.reuseIdentifierLowPriority, forIndexPath: indexPath) as! BubbleCollectionViewCell
    }

    // Give the bubble view the period for it to work on.
    cell.bubbleView.period = period


    // The bubble view needs to monitor a timer to redraw the bubble. Observer is assigned here.
    if let timer = cell.bubbleView.period?.globalTimer {
        timer.observer = cell.bubbleView
    }

    return cell
}

The program breaks on the line cell = collectionView.dequeueReusableCellWithReuseIdentifier(self.reuseIdentifierMediumPriority, forIndexPath: indexPath) as! BubbleCollectionViewCell

I understand an EXC_BAD_ACCESS occurs when an object is accessed after it's autoreleased or when it isn't initialized in the first place. In my case I get the error and have made sure all objects are initialized and their references are strong (not weak). I've enabled NSZombies and had no luck with that.

What is confusing to me is that func collectionView(collectionView:cellForItemAtIndexPath:) -> UICollectionViewCell has executed once already before the thread breaks.

Is this maybe related to the fact I am running on the Test target?

Any help would be greatly appreciated.

Aucun commentaire:

Enregistrer un commentaire