Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCMock 3: Infinite recursion when mocking object that does selector forwarding #126

Open
patrickhartling opened this issue Jul 29, 2014 · 6 comments

Comments

@patrickhartling
Copy link
Contributor

The code base I work on includes several classes that utilize selector forwarding. Each forwarding class has the following code:

- (BOOL)respondsToSelector:(SEL)aSelector
{
    return [super respondsToSelector:aSelector] || [self.otherObject respondsToSelector:aSelector];
}

- (id)forwardingTargetForSelector:(SEL)aSelector
{
    if ([self.otherObject respondsToSelector:aSelector])
    {
        return self.otherObject;
    }
    else
    {
        return [super forwardingTargetForSelector:aSelector];
    }
}

When migrating to OCMock 3 from version 2, I found that infinite recursion would occur if I simply created a partial mock for an instance of one of these classes. I worked around it by changing the first line of ‑forwardingTargetForSelector: to be the following:

    if ([_otherObject respondsToSelector:aSelector])

I made a simple test class that demonstrates the problem.

@erikdoe
Copy link
Owner

erikdoe commented Aug 20, 2014

With the recent changes made in response to some of the other issues reported this problem seems to have been fixed, too. Could you retry whether it works for you now?

@patrickhartling
Copy link
Contributor Author

I will give it a try and get back to you as soon as I can. Thanks for the update.

@patrickhartling
Copy link
Contributor Author

The problem still occurs with the referenced example test case.

@cutz
Copy link

cutz commented Sep 16, 2015

Any update here? I've just recently upgraded some projects to OCMock 3 and am seeing the same issue partial mocking objects with classes that use selector forwarding.

@erikdoe
Copy link
Owner

erikdoe commented May 11, 2021

Many years later I looked into this again. There's still no fix. The problem is that self.otherObject results in sending the method otherObject, which ends up in the partial mock's forwardingTargetForSelector, which then invokes forwardingTargetForSelector on the object, which does self.otherObject... Somehow, when OCMock doesn't do its magic, some other place must detect this condition and break the recursion. I don't know how to do this in OCMock.

@patrickhartling
Copy link
Contributor Author

That sounds like a challenging problem indeed. For what it's worth, we haven't seen this crop up in many years. We needed to reduce reliance on selector forwarding, and avoiding the infinite recursion in tests was an excellent motivator.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

3 participants