我可以设置一个OCMock对象来期待一个char *参数吗?

时间:2013-02-08 17:13:47

标签: ios macos cocoa ocmock

我正在尝试验证是否会在一个模拟对象上调用一个方法,该方法的某个方法的参数具有特定的指针值,但我不断支持“Argument type'*'。”调用mocked方法时的异常。这是我的测试代码:

uint8_t *buf = calloc(65, sizeof(uint8_t));
id stream = [OCMockObject niceMockForClass:[NSInputStream class]];
[[stream expect] read:buf maxLength:64];
id myStream = [[MyStream alloc] initWithStream:stream];
// myStream should pass read:maxLength: call through to stream
[myStream read:buf maxLength:64];
STAssertNoThrow([stream verify], @"Did not pass call through");

这是-[MyStream read:maxLength:]

- (NSInteger)read:(uint8_t *)buffer maxLength:maxLength {
    // internalStream is the stream passed to -initWithStream:
    return [self.internalStream read:buffer maxLength:maxLength];
}

当我在模拟流上调用-read:maxLength:时,我得不到“Argument type'*'。”例外。是否可以期望具有特定指针参数值的调用?

编辑:

看起来这个问题可能特定于char *(或uint8_t )参数。 Objective C @将它们编码为'',而OCMock的类型处理代码仅将'^' - 编码值视为指针。我试过攻击+[OCMArg resolveSpecialValues:]-[NSInvocation getArgumentAtIndexAsObject:](在NSInvocation + OCMAdditions.m中)将'*'视为'^'。这已经停止了例外,但我的期望仍未实现。

有谁知道如何处理这个问题?谢谢!

1 个答案:

答案 0 :(得分:0)

我找到了解决此问题的方法。试图修复OCMock以处理'*' - 编码类型是一个充满伤害的兔子洞,但我能够通过在NSInputStream上创建一个类别来使我的测试工作,这使得它返回OCMock能够使用的方法签名:< / p>

@interface NSInputStream (OCMockFix)
  + (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)selector;
  - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector;
@end

@implementation NSInputStream (OCMockFix)
  + (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)selector {
    if (sel_isEqual(selector, @selector(read:maxLength:))) {
      // Original signature is "i@:*I". Change '*' to '^C'
      return [NSMethodSignature signatureWithObjCTypes:"i@:^CI"];
    } else {
      return [super instanceMethodSignatureForSelector:selector];
    }
  }
  - (NSMethodSignature *)methodSignatureForSelector:(SEL)selector {
    return [[self class] instanceMethodSignatureForSelector:selector];
  }
@end