Reputation: 4914
I have added a button programmatically and I have to run unit test for automation process. We dont have much UI components so we dont use UI testing bundle.
Added button in code
self.proceedButton.frame = CGRectMake(0.0, 0.0, (buttonContainerWidth * 0.75), (buttonContainerHeight * 0.3));
self.proceedButton.center = CGPointMake(self.buttonContainer.center.x, CGRectGetHeight(self.proceedButton.frame));
self.proceedButton.layer.cornerRadius = CGRectGetHeight(self.proceedButton.frame) / 2;
self.proceedButton.layer.masksToBounds = YES;
self.proceedButton.titleLabel.font = proceedFont;
[self.proceedButton addTarget:self action:@selector(onAcceptClicked) forControlEvents:UIControlEventTouchUpInside];
Test:
[vc viewDidLoad];
NSString *selector = [[vc.proceedButton actionsForTarget:vc forControlEvent:UIControlEventTouchUpInside] firstObject];
XCTAssert([selector isEqualToString:@"onAcceptClicked"]);
[vc.proceedButton sendActionsForControlEvents: UIControlEventTouchUpInside];
This fails if I comment out the [self.proceedButton addTarget:self action:@selector(onAcceptClicked) forControlEvents:UIControlEventTouchUpInside];
line so it seems the test is written correctly.
However sendActionsForControlEvents:
is not entering onAcceptClicked
method in the test.
Why this is happening? Is it possible that unit test is finishing before onAcceptClicked
getting actually called?
Upvotes: 1
Views: 574
Reputation: 3497
This could be because you are calling [vc viewDidLoad]
directly, which Apple advises you not to do, presumably because a bunch of setup is performed before viewDidLoad
is eventually invoked.
You should never call this method directly. The view controller calls this method when its view property is requested but is currently nil. This method loads or creates a view and assigns it to the view property.
Instead, try using XCTAssertNotNil(vc.view);
at the beginning. This will try to load the view, eventually calling viewDidLoad
for you and probably setting up your button so that the actions are correctly added to it.
Edit So if it helps, I've just quickly run this test and I can verify that the method onAcceptClicked
is called in the view controller when the test runs.
Button setup in viewDidLoad
CGRect frame = CGRectMake(50, 40, 30, 30);
self.proceedButton = [[UIButton alloc] initWithFrame:frame];
self.proceedButton.titleLabel.text = @"button!!!!";
[self.proceedButton addTarget:self action:@selector(onAcceptClicked) forControlEvents:UIControlEventTouchUpInside];
self.proceedButton.backgroundColor = [UIColor blackColor];
[self.view addSubview:self.proceedButton];
Test
-(void)testButton {
self.myVC = [[UIStoryboard storyboardWithName:@"Main" bundle:nil] instantiateViewControllerWithIdentifier:@"MyVC"];
XCTAssertNotNil(self.myVC.view);
NSString *selector = [[self.myVC.proceedButton actionsForTarget:self.myVC forControlEvent:UIControlEventTouchUpInside] firstObject];
XCTAssert([selector isEqualToString:@"onAcceptClicked"]);
[self.myVC.proceedButton sendActionsForControlEvents: UIControlEventTouchUpInside];
}
Upvotes: 1