11

i'm a new user of OCMock, so maybe i'm just missing something simple here. this code does not compile:

id mockSession = [OCMockObject mockForClass:[AVCaptureSession class]];
[[mockSession expect]  addOutput:[OCMArg anyPointer]];

the error is

Multiple methods named 'addOutput:' found with mismatched result, parameter type or attributes

the signature of the method addOutput on AVCaptureSession is as follows

- (void)addOutput:(AVCaptureOutput *)output

as far as i can tell, the problem is that the method addOutput exists on both the AVCaptureSession and AVAssetReader classes. the method signature for addOutput on AVAssetReader is as follows.

- (void)addOutput:(AVAssetReaderOutput *)output

apparently the compiler thinks my mockSession is an AVAssetReader, but i don't know why it chooses that class instead of AVCaptureSession. if i expect a different method on AVCaptureSession that does not exist on AVAssetReader, then it compiles. i have tried the following without success. it compiles, but crashes.

id mockSession = [OCMockObject mockForClass:[AVCaptureSession class]];
[(AVCaptureSession*)[mockSession expect]  addOutput:[OCMArg anyPointer]];

this code also does not compile, with the same error as the previous one

id mockSession = [OCMockObject mockForClass:[AVCaptureSession class]];
AVCaptureVideoDataOutput *output = [[AVCaptureVideoDataOutput alloc] init];
[[mockSession expect]  addOutput:output];

any guidance here?

Ben H
  • 3,855
  • 1
  • 26
  • 33
  • Why you are creating objects of type `id`? – Anoop Vaidya Jan 25 '13 at 19:18
  • 2
    He's not creating an object of type "id". He's just assigning the object to a variable of type id. The is a common technique with mock objects because using id allows you to pass the object wherever the real one is needed *and* you can call the special methods of the mock object, too. – Erik Doernenburg Jan 26 '13 at 20:02
  • Has anyone seen this for the OCMock methods themselves? I have a completely unrelated class with a method named "reject" and the compiler is giving me same error as OP but it's when I try to use `[mock reject]`. With the newer OCMExpect syntax it wouldn't be an issue but it looks like reject hasn't been converted yet. – danny Jan 07 '15 at 20:40

3 Answers3

17

In cases where your variable is an "id" but a method is declared with different signatures in different classes you should help the compiler by casting the object to the correct type, e.g.

[((AVCaptureSession *)[mockSession expect])  addOutput:[OCMArg any]];

In either case, if the argument is an object, as it seems in your case, you should use any and not anyPointer. But you figured that one out already. ;-)

Erik Doernenburg
  • 2,933
  • 18
  • 21
8

ok, i think it figured it out. as i suspected, it was a simple noob mistake. changing [OCMArg anyPointer] to [OCMArg any] makes the following work:

id mockSession = [OCMockObject mockForClass:[AVCaptureSession class]];
[(AVCaptureSession*)[mockSession expect]  addOutput:[OCMArg any]];
Ben H
  • 3,855
  • 1
  • 26
  • 33
  • 1
    what if `addOutput` being a class method? I know it's a instance method in the question. – John Mar 04 '23 at 07:20
0

You need to inform the compiler that it's fine

#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wobjc-multiple-method-names"
#pragma clang diagnostic ignored "-Wstrict-selector-match"
    OCMStub([globalContextMock sharedContext]).andReturn(context);
#pragma clang diagnostic pop  
Dan Rosenstark
  • 68,471
  • 58
  • 283
  • 421