我试图在Swift中为类扩展编写单元测试。类扩展本身将呈现具有指定标题和消息的UIAlert
:
extension UIViewController {
func presentAlert(title: String, message : String) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil))
UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
}
}
我为单元测试创建了一个包含以下代码的文件:
import XCTest
class AlertTest: XCTestCase {
func testAlert() {
let alert = presentAlert("Presented Alert", "This is an Alert!")
}
}
但是,我一直收到"Use of unresolved identifier 'presentAlert'"
的错误。在咨询SO thread后,我尝试将public
添加到我的扩展程序中:
public func presentAlert(title: String, message : String)
但仍然没有运气。任何人都有一些见解?
修改
根据@hkgumbs的回答,这是我当前的警报扩展代码:
import Foundation
protocol Presentable {}
extension UIViewController {
public func presentAlert(title: String, message : String) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil))
UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
}
}
在视图控制器中,我想要显示警报,这仍然是调用警报的正确方法,对吗?
self.presentAlert("Invalid URL", message: "Please try again")
其次,根据您的评论,这就是我通过在虚拟值上调用Presentable
而理解的内容,但由于SomethingPresentable
没有成员PresentAlert
,这是不正确的。我理解的地方出错了?
func testAlert() {
let app = XCUIApplication()
struct SomethingPresentable: Presentable {}
SomethingPresentable.presentAlert("Presented Alert", message: "This is an Alert!")
XCTAssert(app.alerts["Presented Alert"].exists)
app.alerts["Presented Alert"].tap();
}
编辑2 @hkgumbs,根据您的最新评论,这就是我对扩展的内容:
import Foundation
protocol Presentable {}
extension Presentable {
func presentAlert(title: String, message : String) {
let alertController = UIAlertController(title: title, message: message, preferredStyle: .Alert)
alertController.addAction(UIAlertAction(title: "Close", style: UIAlertActionStyle.Default, handler: nil))
UIApplication.sharedApplication().keyWindow?.rootViewController?.presentViewController(alertController, animated: true, completion: nil)
}
}
这就是我试图从我的ViewController调用它的方式:
Presentable.presentAlert("Invalid URL", message: "Please try again")
但是,我在类型presentAlert
上收到"使用实例成员Self
的错误;你的意思是使用Self
类型的变量吗?"
然后,我猜这是测试的样子?
func testAlert() {
let app = XCUIApplication()
struct SomethingPresentable: Presentable {}
SomethingPresentable.presentAlert("Presented Alert", message: "This is an Alert!")
XCTAssert(app.alerts["Presented Alert"].exists)
app.alerts["Presented Alert"].tap();
}
答案 0 :(得分:4)
如@dan所提到的,您需要从{em> UIViewController
的实例中调用它。通常你不想在你的测试中实例化框架对象,如果你可以避免它,所以这里有一些选项来避免它:
presentAlert
设为静态,以便您可以UIViewController.presentAlert
presentAlert
成为免费功能(不要将其放入扩展程序中) protocol Presentable {}
extension Presentable {
func presentAlert(title: String, message : String) { /* ... */ }
}
然后,只要您需要它,您就可以extension UIViewController: Presentable {}
。在测试中,您可以使用虚拟类。这种方法的另一个好处是,如果需要,您可以在任何类型上重复使用该功能,而不会在您没有全局曝光时使用。
<强>附录强>
当我们扩展协议时,我们说&#34;任何实现此协议的方法都将免费获得此方法。&#34;这里的诀窍是这个协议是空的,因此很容易实现。&#34;
extension YourViewController: Presentable {}