0

我正在尝试验证是否将在具有方法参数之一的特定指针值的模拟对象上调用方法,但我不断收到“不支持参数类型'*'”。调用模拟方法时出现异常。这是我的测试代码:

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: 时,我得到“不支持参数类型'*'”。例外。是否可以期待具有特定指针参数值的调用?

编辑:

看起来这个问题可能特定于 char * (或 uint8_t )参数。Objective C @encodes 将它们编码为 ' ' 并且 OCMock 的类型处理代码只将 '^' 编码的值视为指针。我尝试过黑客攻击+[OCMArg resolveSpecialValues:]-[NSInvocation getArgumentAtIndexAsObject:](在 NSInvocation+OCMAdditions.m 中)将 '*' 视为与 '^' 相同。这已经停止了异常,但我的期望仍然没有得到满足。

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

4

1 回答 1

0

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

@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
于 2013-02-11T16:58:58.400 回答