OCMock method name collision
Asked Answered
J

3

12

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?

Johnsiejohnson answered 25/1, 2013 at 19:14 Comment(3)
Why you are creating objects of type id?Laid
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.Undermost
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.Yaupon
J
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]];
Johnsiejohnson answered 25/1, 2013 at 19:23 Comment(1)
what if addOutput being a class method? I know it's a instance method in the question.Halogen
U
19

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. ;-)

Undermost answered 26/1, 2013 at 20:7 Comment(0)
J
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]];
Johnsiejohnson answered 25/1, 2013 at 19:23 Comment(1)
what if addOutput being a class method? I know it's a instance method in the question.Halogen
W
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  
Woodenhead answered 10/12, 2021 at 22:51 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.