我正在使用OCMock 3来测试我的iOS项目.
我使用dispatch_once()
创建了一个单例类MyManager
:
@implementation MyManager
+ (id)sharedInstance {
static MyManager *sharedMyManager = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
sharedMyManager = [[self alloc] init];
});
return sharedMyManager;
}
Run Code Online (Sandbox Code Playgroud)
我在School
课堂上有一个使用上述单例的方法:
@implementation School
...
- (void) createLecture {
MyManager *mgr = [MyManager sharedInstance];
[mgr checkLectures];
...
}
@end
Run Code Online (Sandbox Code Playgroud)
现在,我想对这个方法进行单元测试,我使用MyManager的局部模拟:
- (void) testCreateLecture {
// create a partially mocked instance of MyManager
id partialMockMgr = [OCMockObject partialMockForObject:[MyManager sharedInstance]];
// run method to test
[schoolToTest createLecture];
... …
Run Code Online (Sandbox Code Playgroud) 我正在遇到路障,我想知道这里出色的集体思想是否有帮助.在ObjC CocoaTouch中,我试图模拟一个接受struct参数并返回结构的对象.OCMock正在咳嗽一个发球,所以我尝试用Hamcrest匹配器包裹.没死.我正在测试的函数/方法看起来像这样:
- (CLLocationCoordinate2D)pixelToLatLong:(CGPoint)aPoint;
Run Code Online (Sandbox Code Playgroud)
我使用这样的代码:
#define OCMOCK_STRUCT(atype, variable) [NSValue value:&variable withObjCType:@encode(atype)]
-(void) testMyWidget
{
CLLocationCoordinate2D ulLL = (CLLocationCoordinate2D){123,456};
CLLocationCoordinate2D lrLL = (CLLocationCoordinate2D){654,321};
[[[(id)myObj expect] andReturn:OCMOCK_STRUCT(CLLocationCoordinate2D, ulLL)] pixelToLatLong:(CGPoint){0,0}];
[[[(id)myObj expect] andReturn:OCMOCK_STRUCT(CLLocationCoordinate2D, lrLL)] pixelToLatLong:(CGPoint){320,460}];//lower right point
}
Run Code Online (Sandbox Code Playgroud)
那有点儿.因此,在我的测试中,我正在测试我进行必要的编辑以获得绿色条...错误..构建信息窗口中的绿色按钮.当我确定我的测试应该通过时,我会得到断言失败的错误.这些错误告诉我该方法被意外调用,并将这些结构的值列为问号.我尝试用Hamcrest匹配器包裹结构但是我无处可去.我正准备打破我的调试器,这无疑会告诉我什么是错的.这里有人和OCMock/Hamcrest和结构有类似的麻烦吗?如果是这样,处理这些类型的最佳方法是什么?
我使用OCMock创建了一个模拟UINavigationController.但是,我不能将它分配给UIViewController的navigationController属性,因为该属性是只读的.
id mockNavController = [OCMockObject mockForClass:[UINavigationController class]];
...
myViewController.navigationController = mockNavController; // readonly!
Run Code Online (Sandbox Code Playgroud)
这篇博文的作者声称找到了一个解决方案,却忽略了分享它.
我正在GET
请求检索JSON
数据,AFNetworking
如下面的代码:
NSURL *url = [NSURL URLWithString:K_THINKERBELL_SERVER_URL];
AFHTTPClient *httpClient = [[AFHTTPClient alloc] initWithBaseURL:url];
Account *ac = [[Account alloc]init];
NSMutableURLRequest *request = [httpClient requestWithMethod:@"GET" path:[NSString stringWithFormat:@"/user/%@/event/%@",ac.uid,eventID] parameters:nil];
AFHTTPRequestOperation *operation = [httpClient HTTPRequestOperationWithRequest:request
success:^(AFHTTPRequestOperation *operation, id responseObject) {
NSError *error = nil;
NSDictionary *JSON = [NSJSONSerialization JSONObjectWithData:responseObject options:NSJSONReadingAllowFragments error:&error];
if (error) {
}
[self.delegate NextMeetingFound:[[Meeting alloc]init] meetingData:JSON];
}
failure:^(AFHTTPRequestOperation *operation, NSError *error){
}];
[httpClient enqueueHTTPRequestOperation:operation];
Run Code Online (Sandbox Code Playgroud)
问题是我想基于这些数据创建单元测试,但我不希望测试实际上会发出请求.我希望预定义的结构将作为响应返回.我是一个新的单元测试,并戳了一点,OCMock
但无法弄清楚如何管理这个.
OCMock为mock类方法提供了一个很好的语法,但类方法调用可以转发到真正的类对象吗?
self.connectionMock = [OCMockObject mockForClass:NSURLConnection.class];
[[[[self.connectionMock stub] andDo:^(NSInvocation *invocation) {
NSURL *url = [invocation getArgumentAtIndexAsObject:2];
NSLog(@"Passing through mock: %@", url);
} ] andForwardToRealObject] connectionWithRequest:OCMOCK_ANY delegate:OCMOCK_ANY];
Run Code Online (Sandbox Code Playgroud)
该问题andForwardToRealObject
仅适用于部分问题.我可以自己调整方法,但是有一种简单的方法可以让我使用OCMock调用原始的类方法吗?
我们正在尝试创建一个单元测试(使用OCMock,虽然对其他框架开放),这样可以模拟一个在类加载时产生副作用的类.
我们有一个跟踪类,可以调用其他跟踪库,如Flurry.
许多其他跟踪库(特别是Flurry)在类初始化时执行代码.
单元测试失败,因为代码无法在单元测试环境中执行.理想情况下,我们想用mock/stub替换Flurry类.
- (void) testConstruction {
[Flurry class];
}
Run Code Online (Sandbox Code Playgroud)
当调用此代码时,它会尝试使用SCNetworkReachability
和接收exceptions
...
我们如何存根/模拟对具有如下静态实现的Flurry的调用?
[Flurry setAppVersion:@"1.0"];
[Flurry setCrashReportingEnabled:NO];
Run Code Online (Sandbox Code Playgroud) 如何验证从未使用OCMock 3调用方法?
我在想这样的事情:
XCTAssertThrows(OCMVerify([_restDataSource getSomeStuff:[OCMArg any]]));
Run Code Online (Sandbox Code Playgroud)
但似乎OCMVerify不会失败.
考虑这个有效的代码(loginWithEmail方法得到预期的,好的,预期的):
_authenticationService = [[OCMockObject mockForClass:[AuthenticationService class]] retain];
[[_authenticationService expect] loginWithEmail:[OCMArg any] andPassword:[OCMArg any]];
Run Code Online (Sandbox Code Playgroud)
与此代码对比:
_authenticationService = [[OCMockObject mockForProtocol:@protocol(AuthenticationServiceProtocol)] retain];
[[_authenticationService expect] loginWithEmail:[OCMArg any] andPassword:[OCMArg any]];
Run Code Online (Sandbox Code Playgroud)
第二个代码示例在第2行失败,出现以下错误:
*** -[NSProxy doesNotRecognizeSelector:loginWithEmail:andPassword:] called! Unknown.m:0: error: -[MigratorTest methodRedacted] : ***
-[NSProxy doesNotRecognizeSelector:loginWithEmail:andPassword:] called!
Run Code Online (Sandbox Code Playgroud)
AuthenticationServiceProtocol声明方法:
@protocol AuthenticationServiceProtocol <NSObject>
@property (nonatomic, retain) id<AuthenticationDelegate> authenticationDelegate;
- (void)loginWithEmail:(NSString *)email andPassword:(NSString *)password;
- (void)logout;
- (void)refreshToken;
@end
Run Code Online (Sandbox Code Playgroud)
它在课堂上实现:
@interface AuthenticationService : NSObject <AuthenticationServiceProtocol>
Run Code Online (Sandbox Code Playgroud)
这是使用OCMock for iOS.
expect
当模拟是一个时,为什么会失败mockForProtocol
?
我有一个iOS应用程序,我试图添加OCMock,以便更好地进行单元测试.我已经按照ocmock.org上的说明以及我在其他地方找到的说明但仍然无法获得我的测试代码进行编译.
这就是我所做的
将源代码添加到我的项目目录中
在我的项目中创建组来模仿我的文件系统
我选择了添加到我的测试目标的选项,以便适当添加框架以及库搜索路径
然后我手动将标题添加到标题搜索路径
并添加了-ObjC链接器标志
然后,当我去导入头文件时,我得到文件未找到错误
我在这里缺少什么想法???
我有一个方法我想用OCMock测试,但不知道如何做到这一点.我需要模拟
ExtClass
哪些未定义为我的代码(外部库)的一部分:
+(NSString *)foo:(NSString *)param
{
ExtClass *ext = [[ExtClass alloc] initWithParam:param];
if ([ext someMethod])
return @"A";
else
return @"B";
}
Run Code Online (Sandbox Code Playgroud)
提前致谢!
ocmock ×10
objective-c ×7
ios ×5
unit-testing ×5
cocoa-touch ×2
afnetworking ×1
cocoa ×1
flurry ×1
hamcrest ×1
iphone ×1
mocking ×1
singleton ×1
xcode ×1
xctest ×1