如何通过依赖MFMailComposeViewController及其类方法进行单元测试?

时间:2017-07-12 17:44:45

标签: ios swift unit-testing mocking

使用Swift,我正在尝试对iOS应用中使用的以下类进行单元测试。如果用户具有系统邮件应用程序设置,则该类显示MFMailComposeViewController;如果未设置系统邮件,则显示警报视图。我不知道测试它的最佳方法。

我不确定如何简单地将MFMailComposeViewController变量添加到类中然后传入一个模拟对象,因为(1)我需要MFMailComposeViewController的类方法canSendMail()和(2)我宁愿MFMailComposeViewController的实例没有在显示和解散后仍然存在。

测试此课程的最佳方法是什么?是否需要重新设计?

public class EmailAction:NSObject, MFMailComposeViewControllerDelegate {

public var name:String
public weak var displayingViewController:UIViewController?
public var email:String
public var subject:String

public init(name:String, email:String, subject:String) {
    self.name = name
    self.email = email
    self.subject = subject
}

@objc public func showEmailComposeViewController() {
    if MFMailComposeViewController.canSendMail() {
        let mailVC = MFMailComposeViewController()
        mailVC.mailComposeDelegate = self
        mailVC.setToRecipients([email])
        mailVC.setSubject(subject)
        displayingViewController?.present(mailVC, animated: true, completion: nil)
    } else {
        let noMailAlert = UIAlertController(title: "Email Not Setup", message: "Setup an email account on this device's Mail app to be able to send mail from this app", preferredStyle: .alert)
        let okButton = UIAlertAction(title: "OK", style: .default, handler: nil)
        noMailAlert.addAction(okButton)
        displayingViewController?.present(noMailAlert, animated: true, completion: nil)
    }
}

public func mailComposeController(_ controller: MFMailComposeViewController, didFinishWith result: MFMailComposeResult, error: Error?) {
    displayingViewController?.dismiss(animated: true, completion: nil)
}

}

1 个答案:

答案 0 :(得分:3)

我会创建一个包含MFMailComposeViewController所需的所有方法的协议:

@objc protocol MailComposeViewController {
    init()
    class func canSendMail() -> Bool
    func setSubject(_: String)
    //... and others
}

我会延长MFMailComposeViewController以符合:

extension MFMailComposeViewController: MailComposeViewController {}

然后我会添加一个MailComposeViewController类作为EmailAction的依赖项。从那里,我可以提供MFMailComposeViewController作为通常的实现,但我也可以提供一个模拟测试。