将结构传递给 OCMock invokeBlockWithArgs 以获得 AVCaptureSession

Passing struct to OCMock invokeBlockWithArgs for AVCaptureSession

我是 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 提供给 "fix" 它:(我试过了;试试 #2

[[stillImageOutputMock expect] captureStillImageAsynchronouslyFromConnection:connectionMock
                                                           completionHandler:([OCMArg invokeBlockWithArgs:(__bridge id)(imageDataSampleBuffer), &error, nil])];

但这会生成一个 EXC_BAD_ACCESS,即使我已经模拟了所有在 completionHandler 中实际使用 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])];