用于 PC Mockito 模拟验证的自定义 Hamcrest 匹配器

Posted

技术标签:

【中文标题】用于 PC Mockito 模拟验证的自定义 Hamcrest 匹配器【英文标题】:Custom OCHamcrest matcher for OCMockito mock verfication 【发布时间】:2013-01-18 04:18:40 【问题描述】:

我正在使用 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: 将包含EAAccessory 的对象作为属性。在我的自定义匹配器中,我需要打开该对象并检查该属性,以确保它与此测试方法中的 accessory 相同。正如我在这里所做的那样,将accessory 传递给匹配器很容易,但是我如何获得传递给参数以在匹配器内部使用的实际对象?或者,我是不是搞错了?

更新

我已经接受了@JonReid 的回答,因为它是一个比我编造的更优雅的解决方案。尽管如此,我认为我正在使用的东西(感谢this 博客文章)可能在其他地方有用:

#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));

【问题讨论】:

【参考方案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)];

【讨论】:

以上是关于用于 PC Mockito 模拟验证的自定义 Hamcrest 匹配器的主要内容,如果未能解决你的问题,请参考以下文章

OCHamcrest 匹配器参数与验证时的 Mockito 模拟不兼容

Mockito:一个强大的用于Java开发的模拟测试框架

使用 mockito 验证对象属性值

Mockito - 验证对象根本没有被调用

使用 Mockito 进行模拟测试的含义是啥 [重复]

JWT 身份验证不适用于 Django 中的自定义控制器