1

我正在使用 OCHamcrest 和 OCMockito 对 iOS 项目进行单元测试。我正在努力理解在对采用参数的方法期望的模拟验证中使用自定义匹配器。特别是,我想验证传递给预期方法的参数之一,但我需要拆开传递的参数才能这样做。为了演示,这是我的测试方法相关部分的内容:

EAAccessory *accessory = mock([EAAccessory class]);
UIViewController <ZKSearchManagerDelegate> *mockController = 
    mockObjectAndProtocol(
        [UIViewController class], @protocol(ZKSearchManagerDelegate)
    );
[verify(mockController) 
        zkZSensorFound:isSensorWithAccessory(accessory) 
     fromSearchManager:_sm];

-zkZSensorFound:fromSearchManager:接受一个包含 aEAAccessory作为属性的对象。在我的自定义匹配器中,我需要打开该对象并检查该属性以确保它与accessory此测试方法中的对象相同。像我在这里所做的那样传递到匹配器很容易accessory,但是如何获取传递给参数以在匹配器内部使用的实际对象?或者,我对这一切都错了吗?

更新

我已经接受了@JonReid 的答案,因为它比我炮制的解决方案要优雅得多。尽管如此,我认为我正在使用的东西(感谢这篇博文)可能在其他地方有用:

#import "ArgumentCaptor.h"

EAAccessory *accessory = mock([EAAccessory class]);
UIViewController <ZKSearchManagerDelegate> *mockController = 
    mockObjectAndProtocol(
        [UIViewController class], @protocol(ZKSearchManagerDelegate)
    );
ArgumentCaptor *captor = argCaptor();
[verify(_mockController) zkZSensorFound:(ZKZSensor *)captor 
                      fromSearchManager:is(sameInstance(_sm))];
ZKZSensor *sensor = captor.argument;
assertThat(sensor.accessory, is(_mockAccessory));
4

1 回答 1

1

首先,请注意,当您没有为 OCMockito 指定匹配器时,它会使用isEqual匹配器。这可能不是您要为第二个参数验证的内容。我会检查身份:

fromSearchManager:sameInstance(_sm)

如果输入参数,它将抱怨匹配器sameInstance不是搜索管理器。解决方法是强制转换匹配器以删除输入:

fromSearchManager:(id)sameInstance(_sm)

现在对于第一个参数:您可能根本不需要制作自定义匹配器。如果您只想检查属性值,请使用hasProperty. 假设该属性名为accessory

zkZSensorFound:(id)hasProperty(@"accessory", sameInstance(accessory))

把它们放在一起:

[verify(mockController) 
        zkZSensorFound:(id)hasProperty(@"accessory", sameInstance(accessory)) 
     fromSearchManager:(id)sameInstance(_sm)];
于 2013-01-18T23:13:49.650 回答