How to get the mocked value when calling isKindOfClass for an OCMock object?
Asked Answered
K

2

12

Passing an OCMock object to a method where the function calls isKindOfClass. However for unit test, the value returned is not of the mocked class but OCMockObject

Knorring answered 1/3, 2013 at 2:10 Comment(5)
OCMockObject appears to be the base class for that framework. Are you calling +(id)mockForClass:Class and wondering why the created object isn't reporting itself as the mocked class?Yanina
If you're still having this issue, can you present your use case? What are you trying to do? Some code would help the analysis.Grandnephew
It can be useful for every factory class that creates objects depending on the class of a parameter. In my case I have to create real objects instead of mock to test these factories.Wraith
Can you clarify your question? You're saying that the "value returned is not of the mocked class", which I read as saying a class object or a class name is returned, but at the same time you're saying that isKindOfClass: is called, and that just returns a boolean. For isKindOfClass: mock objects pretend to be the mocked class, so that should work as you expect.Flamboyant
Let's say I mock a class named "Foo" with niceMockForClass and let's call fooMockedObject the mock. When I call method "class" on fooMockedObject I expect "Foo" but "OCMockObject" is returned. This led isKindOfClass for fooMockedObject return false when we test is fooMockedObject is kindOfClass "Foo".Wraith
E
1

Here is a whole article explaining how exactly to write the OCMock isKindOfClass method (it is not existing by default) and how to use it: http://blog.carbonfive.com/2009/02/17/custom-constraints-for-ocmock/

Eats answered 7/5, 2013 at 9:7 Comment(0)
L
0

If you want to pass OCMock object to a method where the function calls isKindOfClass you need to create partial mock. Following code might help you. It worked for me.

-(void)testMyTest
{
    FirstViewController* masterVC = [[FirstViewController alloc]init];
    SecondViewController *second = [[SecondViewController alloc] init];
    id master = [OCMockObject partialMockForObject:second];
    [[master expect] getName:@"PARAM"];
    [masterVC doSomething:master];
    [master verify];

    [masterVC release];
    [second release];
}

doSomething method inside FirstViewController

-(void)doSomething:(SecondViewController *)detail
{
    if ([detail isKindOfClass:[SecondViewController class]])
    {
        NSString * returnVal = [detail getName:@"PARAM"];
        NSLog(@"returnVal %@",returnVal);
    }
}

One more alternative is mocking the isKindOfClass method, So the test case will become

- (void)testMyTest
{
     CalculatorViewController* masterVC = [[CalculatorViewController alloc]init];
     id master = [OCMockObject niceMockForClass:[SecondViewController class]];
     BOOL ret = YES;
     [[[master expect] andReturnValue:OCMOCK_VALUE(ret)] isKindOfClass:[SecondViewController class]];
     [[master expect] getName:@"PARAM"];
     [masterVC doSomething:master];
     [master verify];
}
Lowestoft answered 7/5, 2013 at 8:44 Comment(6)
The advantage of using a mock/niceMock is that you don't need to instantiate the object. In my case creating that object is difficult.Wraith
ok. One alternative is to mock the isKindOfClass method. something like this id master = [OCMockObject niceMockForClass:[SecondViewController class]]; BOOL ret = YES; // can change the value [[[master expect] andReturnValue:OCMOCK_VALUE(ret)] isKindOfClass:[SecondViewController class]];Lowestoft
What I do is to use a niceMock and stub the method "class" to return the mocked class. This is more reliable to just return YES for any kindOfClass. Why this is not the default behavior of OCMock is unclear for me.Wraith
Check out this link #490648Lowestoft
That link point out that use isKindOfClass is basically incorrect and to use protocols. I'm using a factory class to create object that conforms to a protocol starting from others objects that conforms to another protocols too. This factory will create an object or another one depending on the kind of class. I don't think that this approach is incorrect.Wraith
@Wraith I just went through OCMock forum and found this mulle-kybernetik.com/forum/…Lowestoft

© 2022 - 2024 — McMap. All rights reserved.