質問

I'm not sure if that was the best title, but basically I know that a variable will become instantiated upon running a function. I want to do a partial mock of this variable and expect certain method calls before the variable is instantiated. Here's an example of what I'm trying to do.

-(void)testMethod {
    id mockVar = [OCMock partialMockForObject:self.controller.variable];
    [[mockVar expect] someMethod];

    [self.controller method];
    [mockVar verify];
}

The method inside the controller will look something like:

-(void)method {
    self.variable = [[Class alloc]init];
    [self.variable someMethod];
}

I'm receiving a message like 'doesNotRecognizeSelector'. Is this possible?

役に立ちましたか?

解決

If stubbing the property accessor is a possibility, I would go with that. But if you need to partial mock the instance actually created by the real code, it's possible provided it gets stored on the property -- the setter method becomes the hook -- but it's definitely ugly.

The basic idea is to use OCMArg's checkWithBlock: functionality to intercept the argument to the set method, and create the partial mock at that point. You can assign it to a variable outside the block for verification later on. It would look something like this:

-(void)testMethod
{
    id mockController = [OCMockObject partialMockForObject:self.controller];
    __block id mockVar;

    [[[mockController stub] andForwardToRealObject] setVariable:[OCMArg checkWithBlock:^BOOL(id param) {
        mockVar = [OCMockObject partialMockForObject:param];
        [[mockVar expect] someMethod];
        return YES;
    }]];

    [self.controller method];  // mockVar will be created and assigned during this call
    [mockVar verify];
}

If your real code creates an object and only stores it temporarily in a local variable (not an instance variable), there is really nothing you can do, aside from restructuring your real code to make it easier to test (such as moving the code which creates the object into a new method, which makes it much easier to stub).

他のヒント

It feels like a weird test, but it's possible if you mock the accessor:

-(void)testMethod {
    id mockVar = [OCMock mockForClass:[Class class]];
    id mockController = [OCMock partialMockForObject:controller];
    [[[mockController stub] andReturn:mockVar] variable];
    [[mockVar expect] someMethod];

    [self.controller method];
    [mockVar verify];
}

If you provide a more concrete example of what you're trying to achieve, I could give you a better answer.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top