Class method stubs only affect the exact class that's mocked
I have a superclass/subclass situation where there's a class method that's only implemented in the superclass. The class method is often called as [[self class] classMethod] (as a general pattern in case one of the superclasses decides to override +classMethod). The problem I'm running into is that stubbing +[Superclass classMethod] only works if it's explicitly called as [Superclass classMethod]. If [[self class] classMethod] is called and self is an instance of Subclass, then the original version of +[Superclass classMethod] is invoked rather than the stubbed version.
OCMock's unit test -[OCMockObjectClassMethodMockingTests testStubbingIsOnlyActiveAtTheClassItWasAdded] implies this is on purpose, but I'm not sure why. Is it possible to do something like "stub +[Superclass classMethod] and I don't care how it's invoked"? My ideal behavior would be this. A. Superclass implements +classMethod. B. Subclass1 does not implement +classMethod. C. Subclass2 overrides +classMethod. D. Class mock made of Superclass. E. +classMethod stubbed on the class mock.
- [Superclass classMethod] returns the stubbed value.
- [Subclass1 classMethod] also returns the stubbed value.
- [Subclass2 classMethod] returns Subclass2's normal return value.
The reason is not that the current behaviour is more logical or generally preferable. In fact, the behaviour used to be different. However, the introduction of verify-after-running in OCMock 3 required the introduction of dynamic subclassing on a larger scale and I found it impossible to untangle the setting and resetting of classes taking inheritance into account. So, I switched to the current behaviour.
Could this be kept open for consideration then if the current behavior was more a necessity than something desired?
Hi, Is there any plan to address this enhancement?
As I wrote above, this is a complicated problem, and to be honest, I still don't know how to implement this. So, unless a pull request appears from somewhere, I wouldn't hold my breath...
Thank you Erik for the update.
Can you please help me if there is any other way to achieve this? I am in real need of it. If there is no other way, is it possible for me to revert that commit in my local repo and use the feature?
Please let me know.
There isn't a single commit to revert. This is the consequence of a significant change across the codebase. If you need the method stubbed in subclasses, you have to find the subclasses and stub the method in each class.
Thank you Erik for the update