我有一个应用程序,其中我推UIAlertController
与几个自定义UIAlertAction
s。每个UIAlertAction
在处理器块actionWithTitle:style:handler:
中执行独特的任务。如何使用OCMock测试UIAlertAction处理程序的内容
我有几个方法,我需要验证在这些块内执行。
如何执行handler
块,以便我可以验证这些方法是否已执行?
我有一个应用程序,其中我推UIAlertController
与几个自定义UIAlertAction
s。每个UIAlertAction
在处理器块actionWithTitle:style:handler:
中执行独特的任务。如何使用OCMock测试UIAlertAction处理程序的内容
我有几个方法,我需要验证在这些块内执行。
如何执行handler
块,以便我可以验证这些方法是否已执行?
经过一番玩耍,我终于搞清楚了。原来handler
块可以转换为函数指针,并且可以执行函数指针。
像这样
UIAlertAction *action = myAlertController.actions[0];
void (^someBlock)(id obj) = [action valueForKey:@"handler"];
someBlock(action);
下面是它如何被使用的例子。
-(void)test_verifyThatIfUserSelectsTheFirstActionOfMyAlertControllerSomeMethodIsCalled {
//Setup expectations
[[_partialMockViewController expect] someMethod];
//When the UIAlertController is presented automatically simulate a "tap" of the first button
[[_partialMockViewController stub] presentViewController:[OCMArg checkWithBlock:^BOOL(id obj) {
XCTAssert([obj isKindOfClass:[UIAlertController class]]);
UIAlertController *alert = (UIAlertController*)obj;
//Get the first button
UIAlertAction *action = alert.actions[0];
//Cast the pointer of the handle block into a form that we can execute
void (^someBlock)(id obj) = [action valueForKey:@"handler"];
//Execute the code of the join button
someBlock(action);
}]
animated:YES
completion:nil];
//Execute the method that displays the UIAlertController
[_viewControllerUnderTest methodThatDisplaysAlertController];
//Verify that |someMethod| was executed
[_partialMockViewController verify];
}
带着几分聪明铸造的,我已经找到了一种方法斯威夫特做到这一点(2.2):
extension UIAlertController {
typealias AlertHandler = @convention(block) (UIAlertAction) -> Void
func tapButtonAtIndex(index: Int) {
let block = actions[index].valueForKey("handler")
let handler = unsafeBitCast(block, AlertHandler.self)
handler(actions[index])
}
}
这使您可以调用测试alert.tapButtonAtIndex(1)
,并有正确的处理程序执行。
(我只会用这个在我的测试目标中,顺便说一句)
这在Swift 3.0.1中出现'致命错误:不能unsafeBitCast不同类型的不同大小之间',没有人知道如何解决这个问题? –
我有[找到解决方案](http://stackoverflow.com/a/40634752/17294)。 –
任何想法什么是正确的演员是在斯威夫特?只需转换为预期的函数类型即可在运行时提供“EXC_BAD_INSTRUCTION”。 –