我是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/

10-10 21:50