我正在尝试模拟一个具有以下签名等效方法:
- (NSDictionary *) uploadValues:(BOOL)doSomething error:(NSError **)error
Run Code Online (Sandbox Code Playgroud)
我希望它返回一个小字典,以便我的测试可以确保代码正确使用字典.但是,无论我做什么,OCMock总是从方法中返回nil,无论我如何将其存根.错误在我正在测试的代码中以nil开头,这些是我尝试将其存根的不同方式:
NSError * error = nil;
[[[mock stub] andReturn:someDict] uploadValues:YES error:&error];
[[[mock stub] andReturn:someDict] uploadValues:YES error:nil];
[[[mock stub] andReturn:someDict] uploadValues:YES error:[OCMArg any]];
Run Code Online (Sandbox Code Playgroud)
并且它们都不起作用.OCMock是否支持处理作为存根消息参数,如果是,那么正确的方法是什么?
我有一个在我的类的.m文件中声明的私有属性,我们称之为ClassUnderTest.ClassUnderTest实例化ClassToBeMocked的实例.如何使用OCMock模拟ClassToBeMocked的实例并将其分配给ClassUnderTest?
我正在尝试使用OCMock的stub和Do方法编写一段代码.
在这种情况下,正在测试UIImageView扩展类.我想检查扩展名为[self setImage:]并使用非零参数(稍后将使用其他图像比较).
使用OCMock的andDo方法时,在块完成后,测试将与EXC_BAD_ACCESS崩溃.
id mockView = [OCMockObject mockForClass:[UIImageView class]];
[[[mockView stub] andDo:^(NSInvocation *invocation)
{
UIImage *img;
[invocation getArgument:&img atIndex:2]; <---- line causing the exception
somebodySetImage |= (img != nil);
}] setImage:OCMOCK_ANY];
[mockView do_something_that_calls_setImage];
Run Code Online (Sandbox Code Playgroud)
我现在发现的唯一解决方案是使用andCall而不是andDo,但这使测试变得复杂.
我可以用andDo避免崩溃吗?
更新 嗯,我会尝试在这里给出一个更好的例子:这是测试代码的新部分:
- (void)testDownloadingThumbnail
{
PInfo *_sut = [[PInfo alloc] init];
__block id target = nil;
id mock = [OCMockObject mockForClass:[NSOperationQueue class]];
[[[mock expect] andDo:^(NSInvocation *inv)
{
NSInvocationOperation *op;
[inv getArgument:&op atIndex:2]; …Run Code Online (Sandbox Code Playgroud) 我刚刚练习OCMock,我面临的问题是
我有一个名为fooreturn的CGRect方法,此方法是从另一个方法调用的callFoo.
-(CGRect)foo {
return CGRectMake(10, 10, 10, 10);
}
-(void)callFoo {
CGRect rect = [self foo];
NSLog(@"%@",NSStringFromCGRect(rect));
}
Run Code Online (Sandbox Code Playgroud)
我对callFoo方法的单元测试如下.
- (void)test__callFoo__invokesWithMockingFoo
{
ViewController *sut = [[ViewController alloc] init];
id master = [OCMockObject partialMockForObject:sut];
CGRect rect = CGRectMake(0, 0, 0, 0);
[[[master expect] andReturnValue:OCMOCK_VALUE(rect)] foo];
[sut callFoo];
[master verify];
}
Run Code Online (Sandbox Code Playgroud)
当此测试用例运行,我当它到达得到了意想不到的崩溃CGRect rect = [self foo];
,我想知道为什么这种崩溃是如果我们回到发生CGRect的mocked method,以及如何解决这个崩溃.
任何人都可以帮助解决这个问题.
提前致谢.
PS:如果我用NSValue替换CGRect,这可以正常工作. As shown below
-(NSValue …Run Code Online (Sandbox Code Playgroud) 我的方法的一个参数是**错误,我的项目处于ARC模式.当为此方法编写存根以调用模拟方法时,我将参数设置为以下可能的值.它导致编译错误或无法匹配参数以调用mock方法.
什么都行不通.
如何模仿这种方法?请指教.
编辑
-(id)init{
self = [super init];
if (self) {
id wcm = [OCMockObject partialMockForObject:self];
[[[wcm stub] andCall:@selector(mockGetWakeupCallsForRoomNumber:error:) onObject:self] getWakeupCallsForRoomNumber:OCMOCK_ANY error:((NSError __autoreleasing **) [OCMArg anyPointer])];
//[[[wcm stub] andCall:@selector(testMockMethod) onObject:self] testMethod];
}
return self;
}
-(void)testMethod
{
NSLog(@"Original");
}
-(void)testMockMethod
{
NSLog(@"Mock");
}
-(NSArray*)mockGetWakeupCallsForRoomNumber:(NSString*)roomNumber error:(NSError**)error
{
@throw @"Mock method called";
}
-(NSArray*)getWakeupCallsForRoomNumber:(NSString*)roomNumber error:(NSError**)error
{
}
Run Code Online (Sandbox Code Playgroud)
模拟testMockMethod工作.
将OCMock对象传递给函数调用isKindOfClass的方法.但是对于单元测试,返回的值不是模拟类,而是OCMockObject
我如何对我的NSURLConnection代表进行单元测试?我创建了一个ConnectionDelegate类,它符合不同的协议,以便将数据从Web提供给不同的ViewControllers.在我走得太远之前,我想开始编写单元测试.但我不知道如何在没有互联网连接的情况下将它们作为一个单元进行测试.我还想对待异步回调我应该怎么做.
unit-testing ocmock nsurlconnection ios nsurlconnectiondelegate
我是OCMock的新用户,所以也许我只是在这里错过了一些简单的东西.此代码无法编译:
id mockSession = [OCMockObject mockForClass:[AVCaptureSession class]];
[[mockSession expect] addOutput:[OCMArg anyPointer]];
Run Code Online (Sandbox Code Playgroud)
错误是
Multiple methods named 'addOutput:' found with mismatched result, parameter type or attributes
Run Code Online (Sandbox Code Playgroud)
AVCaptureSession上方法addOutput的签名如下
- (void)addOutput:(AVCaptureOutput *)output
Run Code Online (Sandbox Code Playgroud)
据我所知,问题是方法addOutput存在于AVCaptureSession和AVAssetReader类中.AVAssetReader上addOutput的方法签名如下.
- (void)addOutput:(AVAssetReaderOutput *)output
Run Code Online (Sandbox Code Playgroud)
显然编译器认为我的mockSession是一个AVAssetReader,但我不知道为什么它选择该类而不是AVCaptureSession.如果我期望AVCaptureSession上的另一种方法在AVAssetReader上不存在,那么它就会编译.我试过以下没有成功.它编译,但崩溃.
id mockSession = [OCMockObject mockForClass:[AVCaptureSession class]];
[(AVCaptureSession*)[mockSession expect] addOutput:[OCMArg anyPointer]];
Run Code Online (Sandbox Code Playgroud)
此代码也不编译,与前一个错误相同
id mockSession = [OCMockObject mockForClass:[AVCaptureSession class]];
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
[[mockSession expect] addOutput:output];
Run Code Online (Sandbox Code Playgroud)
这里的任何指导?
这是测试中的方法:
- (void)loginWithUser:(NSString *)userName andPass:(NSString *)pass {
NSDictionary *userPassD = @{@"user":userName,
@"pass":pass};
[_loginCntrl loginWithUserPass:userPassD withSuccess:^(NSString *authToken){
// save authToken to credential store
} failure:^(NSString *errorMessage) {
// alert user pass was wrong
}];
}
Run Code Online (Sandbox Code Playgroud)
我要测试的是,在该成功块中,使用适当的方法调用其他依赖项/ OCMockObject _credStore.所以目前loginCtrl和credStore依赖是OCMockObjects,我可以存根/期望这些.
在调用时,我会将loginController以某种方式执行该块吗?我已经看过一些关于使用OCMock来阻塞块的问题,我无法理解他们正在做的事情以及是否适合这种情况.
实际上我想做的就是OCMock来激活块([成功调用] ??),这样代码_credStore saveUserPass就完成了,可以在_credStore上验证.
我停在哪里:
- (void)test_loginWithuserPass_succeeds_should_call_credStore_setAuthToken {
NSDictionary *userPassD = @{@"user":@"mark",
@"pass":@"test"};
id successBlock = ^ {
// ??? isn't this done in the SUT?
};
[[[_loginController stub] andDo:successBlock] loginWithUserPass:userPassD withSuccess:OCMOCK_ANY failure:OCMOCK_ANY];
[[_credentialStore expect] setAuthToken:@"passed back value from block"];
[_docServiceSUT loginWithUser:@"mark" andPass:@"test"]; …Run Code Online (Sandbox Code Playgroud) 我正在使用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) ocmock ×10
ios ×8
objective-c ×7
unit-testing ×6
iphone ×2
mocking ×2
cocoa-touch ×1
handle ×1
ocunit ×1
singleton ×1
xcode ×1