NSInvocation返回nil

时间:2014-09-08 22:31:04

标签: ios objective-c testing ocmock nsinvocation

有谁知道如何将NSInvocation的参数设置为 nil ? 我正在尝试使用OCMock,我希望这个期望能够返回nil。问题是,在调用方法时我需要做其他事情,正如您在示例中看到的那样,这就是为什么我没有做andReturn:nil

我想这样做:

[[[myObject stub] andDo:^(NSInvocation *inv) {
   [inv setReturnValue:Nil];
   [inv invoke];
   [self notify:kXCTUnitWaitStatusSuccess]; //Code that I need to execute
}] myMethod:OCMOCK_ANY];

但是我收到了一个错误:

 *** Terminating app due to uncaught exception 
 'NSInvalidArgumentException', reason: '-[NSInvocation setArgument:atIndex:]: 
 NULL address argument'

任何人都知道是否有另一种方法将其设置为零?或者如果它是不可能的?

2 个答案:

答案 0 :(得分:2)

首先,您的代码并没有多大意义。您应该在调用调用之前设置调用的参数,调用的方法将读取您为其提供的参数,并设置返回值,然后您可以在调用调用后读取返回值。在调用它之前设置返回值是没有意义的,因为"返回值"根据定义,事物"返回"作为调用的结果,将在调用结束时设置,覆盖之前设置的任何内容。

要解决您所遇到的错误,对于所有getArgumentsetArgumentgetReturnValuesetReturnValue函数,您需要将指针传递给缓冲区要读取或写入值的位置。这是因为参数和返回值可以是各种大小的各种C类型,因此您无法直接传递它。在这种情况下,似乎要读/写的值是一个对象指针,所以你需要创建一个对象指针类型的变量,设置为你想要的值(在你设置的情况下),然后你将指向此变量的指针传递给getArgument / setArgument / getReturnValue / setReturnValue

答案 1 :(得分:0)

@newacct说明了这一点,他是完全正确的。在实际调用之前,不能设置调用的返回值。我做了什么来获得" nil"因为调用的结果是修改调用的参数,因此调用将调用的代码会生成nil。让我用一个例子解释一下:

- (void)viewDidLoad {
  NSString *arg = @"HelloWorld";

  NSInvocation *invocation = [NSInvocation invocationWithMethodSignature:[self methodSignatureForSelector:@selector(isHelloWorld:)]];
  [invocation setSelector:@selector(isHelloWorld:)];
  [invocation setTarget:self];
  [invocation setArgument:&arg atIndex:2];

  NSString *result1 = nil;
  [invocation invoke];
  [invocation getReturnValue:&result1];

  NSString *result2 = [self resultOfModifiedInvocation:invocation];

  NSLog(@"result 1: %@",result1);
  NSLog(@"result 2: %@",result2);
}

- (NSString *) resultOfModifiedInvocation:(NSInvocation *) invocation {
  NSString *aString = @"NoWorld";
  [invocation setArgument:&aString atIndex:2];

  [invocation invoke];
  [invocation getReturnValue:&aString];

  return aString;
}


- (NSString *) isHelloWorld:(NSString *) aString{
  if([aString isEqualToString:@"HelloWorld"])
    return aString;
  else
    return nil;
}

方法isHelloWorld:应该返回@"HelloWorld",因为我们在调用中发送的内容是正确的。这实际上是在您第一次调用调用时发生的,因为参数尚未被修改。另一方面,通过调用resultOfModifiedInvocation:调用的参数被修改,然后调用的结果是不同的。

这是示例的输出:

  > result 1: HelloWorld
  > result 2: (null)