0

I'm trying to use OCMock to modify the behavior of an instance selector for a specific class where I don't have a direct pointer to the instance of the class in question.

I've found a few posts online that claim to allow doing at least part of this, for example: How to mock an object with OCMock which isn't passed as a parameter to method?

I tried following the guidance in one of the answers in that post, specifically relying on code like this:

id mockController = OCMClassMock([WebAuthViewController class]);
OCMStub([mockController alloc]).andReturn(mockController);
OCMStub([mockController initWithAuthenticationToken:OCMOCK_ANY authConfig:OCMOCK_ANY]).andReturn(mockController);

However, I am having difficulty understanding this code. First of all, where does the actual "alloc" logic run? The code seems to be saying "mock alloc and return an existing class method", but alloc is supposed to return an instance, not a class. Is this some magic build into OCMock?

Also, on a related matter it seems the init is simply returning the same mocked class, not an instance of that class. It seems really strange that this returns the same thing as the previous mock, and I don't understand where the actual custom init logic is being called. It seems to be omitted completely since there is no call to .andForwardToRealObject() anywhere.

However, ultimately my main problem is I don't understand how to mock an instance method using the above code since things are working on class, not an instance. I tried to write a similar mock to modify the behavior of an instance method (using the equivalent of mockController above), but it said the method was not there.

I tried a bunch of things, but could not get OCMock to handle this case. If anyone can point me to an example that mocks a specific instance method for all instances of a class, I'd appreciate it.

By the way, I was able to get things working by using swizzling without any use of OCMock, but it seems really hacky (especially when I'm using OCMock for everything else), so I would love to get this working with OCMock.

Hiren Dhamecha
  • 658
  • 5
  • 15
Locksleyu
  • 5,192
  • 8
  • 52
  • 77
  • First off, an instance of `OCMClassMock` can be used to mock both, class and instance methods of the class that it is created for. This might help understand the `alloc`/`init` trickery (which I recommend to avoid if at all possible). Regarding your real question, can you clarify how the instance of the internal object is created? – Erik Doernenburg Mar 04 '20 at 20:27
  • The instance of the internal object is created dynamically as part of a selector of another object. I'd rather not stub that out since there is other logic in that selector besides the object creation. As for the instance of the OCMClassMock, it may be possible to be used to mock both, but it seems that the way I am using it, it is only working for class methods. – Locksleyu Mar 05 '20 at 17:48
  • I understand that the instance is created in another method. The question is how, precisely, is it created? Does that method do an alloc/init? Does it use another method? A class method? This is important, because if you don't want to inject the object that needs to be mocked from the outside, then you need to stub its creation so that you can create a mock instead of the real object. – Erik Doernenburg Mar 05 '20 at 21:13

0 Answers0