Bernard
Bernard

Reputation: 4580

How to test BarButtonItem is connected to right IBAction?

I have seen this for a normal UIButton:

NSArray *actions = [viewController.addButton actionsForTarget:viewController forControlEvent:UIControlEventTouchUpInside];
XCTAssertTrue([actions containsObject:@”addNumbers:”], @””);

But now I want to do same thing for a rightBarButtonItem! I have tested this button exist on the VC but there is no interface actionForTargets!

I tried this also but it did not work:

NSArray *actions = [self.navigationItem.rightBarButtonItem actionsForTarget:self forControlEvent:UIControlEventTouchUpInside];

or

NSArray *actions = [[self.navigationItem.rightBarButtonItem target] actionsForTarget:self forControlEvent:UIControlEventTouchUpInside];

Non of them works. Anyone has written test code for a UIBarButton to check if button is connected to correct IBAction?

Upvotes: 1

Views: 138

Answers (1)

cncool
cncool

Reputation: 1026

You can loop through the subviews of the navigationBar, and find a UIControl whole allTargets method contains the rightBarButtonItem.

Once you have that, you can call actionForTarget:forControlEvents: on that UIControl, where the rightBarButtonItem is the target, and UIControl's allControlEvents is the forControlEvents parameter:

//get the underlying control
for(UIControl * control in self.navigationController.navigationBar.subviews)
{
    if([control isKindOfClass:UIControl.class])
    {
        //we found the right one
        if([control.allTargets containsObject:self.navigationItem.rightBarButtonItem])
        {
            NSArray <NSString*> * actions = [control actionsForTarget:self.navigationItem.rightBarButtonItem forControlEvent:[control allControlEvents]];

            //do something with actions.firstObject;

            return;
        }
    }
} 

However, I believe the subviews of the UINavigationBar has no publicly defined layout, so this is a fragile solution.

Upvotes: 0

Related Questions