erikdoe / ocmock

Mock objects for Objective-C
http://ocmock.org
Apache License 2.0
2.16k stars 606 forks source link

Stub of class method won't match #441

Closed abbeycode closed 4 years ago

abbeycode commented 4 years ago

I've been tearing my hair out trying to figure out why one of my class stubs that worked on OCMock v2.x isn't working now with v3.6. This is the class method signature:

@interface MyClass : NSManagedObject
...
+ (NSDictionary *)publicXMLFields;
...
@end

I'm stubbing it like so:

    id classMock = OCMClassMock([MyClass class]);
    OCMStub([classMock publicXMLFields]).andReturn(@{@"dateField" : @"DATE"});

    NSDictionary *fields = [MyClass publicXMLFields];
    XCTAssertEqual(fields.count, 1);

The assertion fails, because it's calling through to the class's implementation. If I invoke the method on classMock instead of MyClass, I get this:

/.../Pods/OCMock/Source/OCMock/OCMockObject.m:466: error: -[MyTest testUnsupportedFormatType] : failed: caught "NSInvalidArgumentException", "-[OCMockObject(MyClass) publicXMLFields]: unrecognized selector sent to instance 0x102122b10"

There's another more complicated class method exhibiting the same behavior.

I'm completely stuck. I've tried tinkering with the OCMArg matchers, tried using the ClassMethod macro, and other more subtle tweaks, but I'm out of ideas. What am I missing? Does it matter that MyClass is a Core Data class, deriving from NSManagedObject?

erikdoe commented 4 years ago

Apologies. This is a known problem; see https://github.com/erikdoe/ocmock/issues/339#issuecomment-392204720. However, I obviously forgot to add this to limitations section in the documentation. I'll leave this issue open until I have time to document this limitation.

abbeycode commented 4 years ago

That's interesting, but you stated:

you cannot stub/mock class methods on NSObject for subclasses of NSManagedObject

Does the limitation apply equally to custom methods defined on the NSManagedObject subclass, as is the case for me?

erikdoe commented 4 years ago

The way I phrased this in the comment is a bit odd. The code is much clearer. Here's the commit with the change (line 90-93): https://github.com/erikdoe/ocmock/commit/c06779c5876740874eac64e301da3ba00523f894?diff=unified