您的位置:首页 > 其它

浅谈单元测试中Mock的使用

2015-04-23 01:30 211 查看


何为mock?

mock测试就是在测试过程中中,对于某些不容易构造或者不容易获取的对象,用一个虚拟的对象来创建以便测试的测试方法。

mock对象

mock对象就是真实对象在测试期间的代替品。

mock对象使用场景

真实对象具有不可确定的行为,有时真实对象的某些行为很难被触发。

mock测试的关键步骤

在测试代码中实现对于真实对象的mock,而在被测试代码中只是通过接口来引用对象,所以它不知道这个引用的对象是真实对象还是mock对象。

个人理解,mock对象是在测试过程中对于真实对象的一种替代,通过mock的手段可以使在某些特定条件下才会被触发的行为变得可控,也就是一种“去依赖”的方法。举例来说,在今年圣诞节的某个时间点,公司的所有电脑会同时播放一小段视频提醒大家圣诞节的到来,如果要利用真实的对象来测试的话,就只能等到圣诞节那天的那个时间点去验证了,但利用mock对象,我们就可以对时间点进行伪造来进行测试了。

本文基于OCMock库,简单介绍在Objective-C代码的单元测试中对于mock的使用。


创建不同类型的mock


任意类型的mock

id mockA = [OCMock mockForClass[A class]];

这种方式创建的mock对象,如果调用未stub的方法,会抛出一个异常。这需要保证在mock的生命周期中每一个独立调用的方法都是被存根的。

Nice Mock

id niceMockA = [OCMock niceMockForClass[A class]];

如果你不想自己对很多的方法进行存根,那么使用nice mock。Nice
mock是比较友好的,当一个没有存根的方法被调用时他不会引起一个异常

Partial Mock

当调用一个没有被存根的方法时,会调用实际对象的该方法。当不能很好的存根一个类的方法时,该技术是非常有用的。另外,对于单例类的mock也需要使用partialMock。

如: id aMock = [OCMockObject partialMockForObject:[UIApplicationsharedApplication]];


Stub与Expect的使用

场景:假如我们的待测代码中有一个Car类,Car类中有一个方法为goFaster:units: ,我们的待测函数A需要传入一个Car对象,而A内部一些条件依赖于goFaster:units:的返回值。

stubbed methods(存根方法)

id mockCar = [OCMockmockForClass[Car class]];

[[[mockCar stub]andReturn:@"75kph"] goFaster:[OCMArg any] units:@"kph"];

这样当我们这样调用时:

[mockCar goFaster:84units:@”kph”],该方法就会返回我们指定的值了(andReturn:期望返回的值)。

注:

1、[OCMArg any]告诉stub采用任意参数值。

2、stub方法意味着方法被调用0或多次,上面的例子中就是待测函数A调用了goFaster:units:方法0或多次。

expect方法

在OCMock中,expect意为着方法必须被调用,且只能被调用一次。

[[[mockCar expect]andReturn:@"75kph"] goFaster:[OCMArg any] units:@"kph"];

注:如果用expect来伪造goFaster方法的话,expect的使用次数与待测函数A中方法的调用次数需一致,否则会抛出异常。


Mock类方法

若没有实例方法与类方法同名,OCMock会在mock实例上面找到类方法,若有实例方法与类方法同名,通过下面的方法mock类方法:

[[[[A stub]classMethod] andReturn:@""] xxx];

注:xxx为mock的方法名。


验证方法是否被调用

验证一个方法是否被调用是比较简单的。这能够通过使用expect、reject和verify方法来实现。

id niceMockA = [OCMockniceMockForClass[A class]];

[[niceMockAexpect] greeting:@"hello"];

[niceMockAverify];





原文链接

如需转载该篇文章,请注明来自“搜狗测试”
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息