首页 > 其他分享 >OCMock 的使用方法

OCMock 的使用方法

时间:2023-06-16 14:34:18浏览次数:37  
标签:OCMock NSString 存根 str 使用 formatter 方法 mockA

(一)置换方法(存根):告诉 mock 对象,当 someMethod 被调用,返回什么值

调用方式:

d jalopy = [OCMock mockForClass[Car class]];
OCMStub([jalopy goFaster:[OCMArg any] units:@"kph"]).andReturn(@"75kph");

使用场景:

1. 验证 A 方法时,A 方法内部使用 B 方法的返回值但是 B 方法内部逻辑比较复杂,这时需要使用 stub 方法去存根 B 方法的返回值。代码实现类似下面代码实现固定 funcB 的返回值,做到在不影响源代码的条件下,获取满足测试需要的参数。

方法进行存根前

- (NSString *)getOtherTimeStrWithString:(NSString *)formatTime{
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; //(@"YYYY-MM-dd hh:mm:ss") ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制
    //设置时区选择北京时间
    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Beijing"];
    [formatter setTimeZone:timeZone];
    NSDate* date = [formatter dateFromString:formatTime]; //------------将字符串按formatter转成nsdate
    //时间转时间戳的方法:
    NSInteger timeSp = [[NSNumber numberWithDouble:[date timeIntervalSince1970]] integerValue] * 1000;
    return [NSString stringWithFormat:@"%ld",(long)timeSp];
}

使用stub(mockObject getOtherTimeStrWithString).andReturn(@"1000")存根后类似于以下效果

- (NSString *)getOtherTimeStrWithString:(NSString *)formatTime{
    
    return @"1000";
    
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateStyle:NSDateFormatterMediumStyle];
    [formatter setTimeStyle:NSDateFormatterShortStyle];
    [formatter setDateFormat:@"YYYY-MM-dd HH:mm:ss"]; //(@"YYYY-MM-dd hh:mm:ss") ----------设置你想要的格式,hh与HH的区别:分别表示12小时制,24小时制
    //设置时区选择北京时间
    NSTimeZone* timeZone = [NSTimeZone timeZoneWithName:@"Asia/Beijing"];
    [formatter setTimeZone:timeZone];
    NSDate* date = [formatter dateFromString:formatTime]; //------------将字符串按formatter转成nsdate
    //时间转时间戳的方法:
    NSInteger timeSp = [[NSNumber numberWithDouble:[date timeIntervalSince1970]] integerValue] * 1000;
    return [NSString stringWithFormat:@"%ld",(long)timeSp];
}

2. 代码正常流程经过测试已经很健壮了,但是一些错误的流程并不容易发现但是是可能存在的,例如边缘值数据,单元测试中可以使用存根对数据进行模拟,测试代码在特殊数据情况下的运行情况。

注:stub()也可以不设置返回值,验证可行,猜测可能是返回的nil或者void,所以不带返回值的方法也可以进行方法存根。

(二)生成 Mock 对象,目前有三种方式。

通过对Person类的talk方法进行测试举例,其中也涉及Men类以及Animaiton类,以下是三个类的相关源码。

Person类

@interface Person()
@property(nonatomic,strong)Men *men;
@end


@implementation Person
-(void)talk:(NSString *)str
{
    [self.men logstr:str];
    [Animaiton logstr:str];
    
}
@end

Men类

@implementation Men
-(NSString *)logstr:(NSString *)str
{
    NSLog(@"%@",str);
    return str;
}
@end

Animaiton类

@implementation Animaiton
+(NSString *)logstr:(NSString *)str
{
    NSLog(@"%@",str);
    return str;
}
-(NSString *)logstr:(NSString *)str
{
    NSLog(@"%@",str);
    return str;
}
@end

对talk方法进行单测时需要对person类进行mock,以下是通过三种不同的方式生成mock对象,对三种方式的调用方法,使用场景都做了介绍,最后对每种方式的优缺点也做了一个表格方便区别。

Nice Mock

NiceMock 创建的 mock 对象在进行方法测试时会优先调用实例方法,若未找到实例方法,会继续调用同名的类方法。因此该方法可以用来生成mock对象去测试类方法也可以测试对象方法。

使用方式:

- (void)testTalkNiceMock {
    id mockA = OCMClassMock([Men class]);
    Person *person1 = [Person new];
    person1.men = mockA;
    [person1 talk:@"123"];
    OCMVerify([mockA logstr:[OCMArg any]]);
}

使用场景:

Nice mock 是比较友好的,当一个没有存根的方法被调用时他不会引起一个异常会验证通过。如果你不想自己对很多的方法进行存根,那么使用 nice mock。在上方的举例中mockA调用testTalkNiceMock时,Men类中的+(NSString *)logstr:(NSString *)str不会执行打印操作。在调用过程中因为同时存在同名的logstr:类方法和实例方法,会优先调用实例方法。

Strict Mock

使用方式:

测试case如下,mockA是Strict Mock生成要调用testTalkStrictMock方法,则Mock生成要调用testTalkStrictMock方法则该方法要使用stub进行存根,否则最后的OCMVerifyAll(mockA)就会抛出异常。

- (void)testTalkStrictMock {
    id mockA = OCMStrictClassMock([Person class]);
    OCMStub([mockA talk:@"123"]);
    [mockA talk:@"123"];
    OCMVerifyAll(mockA);
}

使用场景:

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

Partial Mock

这样创建的对象在调用方法时:如果方法被 stub,调用 stub 后的方法,如果方法没有被 stub,调用原来的对象的方法,该方法有限制只能 mock 实例对象。

使用方式:

- (void)testTalkPartialMock {
    id mockA = OCMPartialMock([Men new]);
    Person *person1 = [Person new];
    person1.men = mockA;
    [person1 talk:@"123"];
    OCMVerify([mockA logstr:[OCMArg any]]);
}


标签:OCMock,NSString,存根,str,使用,formatter,方法,mockA
From: https://blog.51cto.com/u_16163254/6499491

相关文章

  • OpenIddict使用教程
    @@openiddictpassword模式流程 OpenIddict是一个ASP.NETCore身份验证库,可帮助您添加OpenIDConnect和OAuth2.0支持到ASP.NETCore应用程序中。下面是OpenIddict使用教程的步骤:安装OpenIddict,在项目中添加OpenIddict.Core和OpenIddict.EntityFrameworkCoreNuget包。......
  • JavaScript 数组展平方法: flat() 和 flatMap()
    JavaScript数组展平方法:flat()和flatMap()从ES2019中开始引入了一种扁平化数组的新方法,可以展平任何深度的数组。flatflat()方法创建一个新数组,其中所有子数组元素以递归方式连接到特定深度。语法:array.flat(depth)array:flat()方法将在给定的数组中使用。depth......
  • 使用Postman的Get请求遇到:"type": "parsing_exception","reason": "Unknown
    错误如图原因postman自身的的bug问题。body里面写了json参数,结果postman将GET请求当成POST请求了。解决办法删掉json数据,或者重新建立一个连接。......
  • 隧道模式HTTP使用教程
    华科隧道HTTP格式为:服务器:端口账号密码隧道代理分钟2种模式:固定时间更改新IP(比如5分钟,10分钟,初次开通的时候可设定)请求一次更换一个新IP(可通过浏览器或者curl)1、使用浏览器1.1、使用浏览器切换IP(限制180次/小时,间隔>20秒)用浏览器访问 http://ip.hahado.cn/simple/switch-ip......
  • CHAT-GPT初使用
    拿chatgpt去试验了一下,一个挺小的需求,但是前后还是更改了三次,体验就是它可以不断改进之前实现的代码,但需要提需求的人比较清楚需求内的细节,差不多类似于,我有想法,它来实现,还是可以提高不少效率的。具体体验如下:我:请写一段C语言代码,将2M大小的文件填充0xff到30M,要求不能申请超过1K......
  • 服务器22端口没有对外开放,那使用ping命令还能通吗
       `ping`命令是基于ICMP协议的网络诊断工具,主要用于测试网络通信是否正常以及测量数据包往返时间等。它并不依赖于任何端口开放与否的情况,因此即使你的服务器的22端口没有对外开放,使用`ping`命令一样可以进行网络通信测试。当你使用`ping`命令测试某个服务器时,它会发......
  • Go语言之 go-redis 基本使用
    Go语言之go-redis基本使用Redis介绍Redis:https://redis.io/Redis中文网:https://www.redis.net.cn/REmoteDIctionaryServer(Redis)是一个由SalvatoreSanfilippo写的key-value存储系统。Redis是一个开源的使用ANSIC语言编写、遵守BSD协议、支持网络、可基于内存亦可持......
  • Python中常用set()方法详解!
    set是Python中一种集合数据类型,表示一个无序且不重复的集合。set()方法可以用于创建一个空的集合,也可以将其他可迭代对象转换为集合。与其他Python数据类型不同,set没有索引,不能通过索引访问其元素,但可以使用一些方法来操作和访问集合中的元素。1、add():添加一个元素到set集......
  • 云原生之使用Docker部署kkFileView在线文档管理平台
    (云原生之使用Docker部署kkFileView在线文档管理平台)一、kkFileView介绍1.kkFileView简介kkFileView是一个开源在线文档工具,使用springboot打造文件文档在线预览项目解决方案,支持doc、docx、ppt、pptx、xls、xlsx、zip、rar、mp4、mp3以及众多类文本如txt、html、xml、java、......
  • js保留小数的方法(如保留一位小数)
     js保留小数的方法如下:(以保留两位为例)1、toFixed()方法需注意,保留两位小数,将数值类型的数据改变成了字符串类型//1.四舍五入varnum=1.7321;num=num.toFixed(2);console.log(num);//1.73console.log(typeofnum);//string2、Math.floor(),不四舍五入......