我是OCMock的新手,正在尝试对使用AVCaptureSession的相机应用程序进行单元测试。
我正在尝试对捕获静止图像并将其传递的方法进行单元测试。
我在嘲笑AVCaptureStillImageOutput的captureStillImageAsynchronouslyFromConnection:completionHandler:
时遇到问题。问题在于将CMSampleBufferRef
传递给completionHandler。我真的不在乎CMSampleBufferRef的内容是什么,除非它不能为nil / null。对于单元测试用例,在完成处理程序中唯一引用它的时间是if ( imageDataSampleBuffer ) {
...我嘲笑的所有其他用法。
这是我尝试过的:
设定:
NSError *error = nil;
CMSampleBufferRef imageDataSampleBuffer;
stillImageOutputMock = OCMStrictClassMock([AVCaptureStillImageOutput class]);
尝试#1:
[[stillImageOutputMock expect] captureStillImageAsynchronouslyFromConnection:connectionMock
completionHandler:([OCMArg invokeBlockWithArgs:imageDataSampleBuffer, &error, nil])];
给出编译器错误:
/Users/.../UnitTests/Unit/CameraViewController/CameraViewControllerTests.m:195:152: Implicit conversion of C pointer type 'CMSampleBufferRef' (aka 'struct opaqueCMSampleBuffer *') to Objective-C pointer type 'id' requires a bridged cast
Xcode提供了“修复”功能:(我尝试过;尝试#2)
[[stillImageOutputMock expect] captureStillImageAsynchronouslyFromConnection:connectionMock
completionHandler:([OCMArg invokeBlockWithArgs:(__bridge id)(imageDataSampleBuffer), &error, nil])];
但这会生成EXC_BAD_ACCESS,即使我已经模拟了实际上在完成处理程序内部使用imageDataSampleBuffer的所有方法。异常来自OCMock,它在其中将imageDataSampleBuffer添加到args数组中
+ (id)invokeBlockWithArgs:(id)first,... NS_REQUIRES_NIL_TERMINATION
{
NSMutableArray *params = [NSMutableArray array];
va_list args;
if(first)
{
[params addObject:first]; <<<<<< EXCEPTION HERE. first isn't an object
va_start(args, first);
尝试#3:
OCMock文档指出了
non-object arguments must be wrapped in value objects and the expression must be wrapped in round brackets.
,所以我尝试了:[[stillImageOutputMock expect] captureStillImageAsynchronouslyFromConnection:connectionMock
completionHandler:([OCMArg invokeBlockWithArgs:@(imageDataSampleBuffer), &error, nil])];
但是编译器抱怨:
/Users/.../UnitTests/Unit/CameraViewController/CameraViewControllerTests.m:196:119: Illegal type 'CMSampleBufferRef' (aka 'struct opaqueCMSampleBuffer *') used in a boxed expression
有什么建议吗?
我能够像
[OCMArg invokeBlock]
那样运行它:[[stillImageOutputMock expect] captureStillImageAsynchronouslyFromConnection:connectionMock
completionHandler:[OCMArg invokeBlock]];
但是补全处理程序会为imageDataSampleBuffer获取0x0,并且会跳过补全处理程序中所有有趣的功能。
最佳答案
啊,我发现解决方案深入了OCMock tests(特别是OCMockObjectTests.m)
OCMOCK_VALUE()达到了目的。这是工作语法:
NSError *error = nil;
CMSampleBufferRef imageDataSampleBuffer;
stillImageOutputMock = OCMStrictClassMock([AVCaptureStillImageOutput class]);
[[stillImageOutputMock expect] captureStillImageAsynchronouslyFromConnection:connectionMock
completionHandler:([OCMArg invokeBlockWithArgs:OCMOCK_VALUE(imageDataSampleBuffer), OCMOCK_VALUE(&error), nil])];
关于ios - 将结构传递给OCMock invokeBlockWithArgs用于AVCaptureSession,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/35946953/