简体   繁体   English

使用XCTest测试PresentedViewController

[英]Test PresentedViewController with XCTest

I have method which I would like to test: 我有方法,我想测试:

- (void)sendMailToContact:(Contact *)conact
{
    self.contact = conact;

    if ([self isSendingAvaiable]) {

        MFMailComposeViewController *mailViewController = [[MFMailComposeViewController alloc] init];
        mailViewController.mailComposeDelegate = self;
        [mailViewController setToRecipients:@[self.contact.email]];

        [self.parentViewController presentViewController:mailViewController animated:YES completion:nil];
    }
}

The test... 考试...

- (void)testSendMailToContact_itShouldShowMFMailComposeViewController
{
    UIViewController *mockViewController = [[UIViewController alloc] init];
    [mockViewController viewDidLoad];

    MailComposer *mockMailComposer = [MailComposer sharedComposerWithController:mockViewController];

    [mockMailComposer sendMailToContact:[self mockContact]];

    XCTAssertTrue([mockViewController.presentedViewController isKindOfClass:[MFMailComposeViewController class]], @"");
}

But It not work correctly. 但它无法正常工作。 I should have MFMailComposeViewController as presentedViewController but I have null. 我应该将MFMailComposeViewController作为presentViewController,但我有null。 I don't know what to do. 我不知道该怎么办。 Please help! 请帮忙!

The problem is that mockViewController is not in UIWindow hierarchy. 问题是mockViewController不在UIWindow层次结构中。 Try: 尝试:

[UIApplication sharedApplication].keyWindow.rootViewController = mockViewController;

Then you can also get rid of viewDidLoad call. 然后你也可以摆脱viewDidLoad调用。

Here's the Swift 4 solution: 这是Swift 4解决方案:

let vc = UIViewController()
UIApplication.shared.keyWindow?.rootViewController = vc

In your test… 在你的测试中......

XCTAssert(vc.presentedViewController is MyCustomViewController)

Your test case contains some issues. 您的测试用例包含一些问题。 You are presenting the MFMailComposeViewController from MailComposer . 您将从MailComposer呈现MFMailComposeViewController So you should call the presentedViewController on mockMailComposer not on mockViewController . 所以,你应该叫presentedViewControllermockMailComposer不是mockViewController

Change that to: 改为:

- (void)testSendMailToContact_itShouldShowMFMailComposeViewController
{
    MailComposer *mockMailComposer = [MailComposer sharedComposerWithController:mockViewController];

    [mockMailComposer sendMailToContact:[self mockContact]];

    XCTAssertTrue([mockMailComposer.presentedViewController isKindOfClass:[MFMailComposeViewController class]], @"");
}

It looks as though you need 2 parts to your test (or 2 separate tests). 看起来你的测试需要2个部分(或2个单独的测试)。 The first part should ensure that isSendingAvaiable is NO and test that mockViewController.presentedViewController is nil . 第一部分应确保isSendingAvaiableNO并测试mockViewController.presentedViewControllernil The second part should ensure that isSendingAvaiable is YES and test that mockViewController.presentedViewController is of the appropriate class. 第二部分应确保isSendingAvaiableYES并测试mockViewController.presentedViewController是否为适当的类。

When a test fails it is important to determine whether the fault lies with the code being testing or with the test itself. 当测试失败时,确定故障是在测试代码还是测试本身是很重要的。

Perhaps the issue is that isSendingAvaiable is NO . 也许问题是isSendingAvaiableNO

Add your root ViewController instance to a UIWindow before testing, no need to use UIApplication.shared.keyWindow?.rootViewController as mentioned above. 在测试之前将根ViewController实例添加到UIWindow,如上所述,不需要使用UIApplication.shared.keyWindow?.rootViewController

let window = UIWindow()
window.rootViewController = yourRootViewController
window.makeKeyAndVisible()


XCTAssert(yourRootViewController.presentedViewController is YourModalViewController)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM