ocmock icon indicating copy to clipboard operation
ocmock copied to clipboard

OCMExpect from selector

Open blackivory86 opened this issue 9 years ago • 4 comments

Maybe this is an 'esoteric' feature request but I'd like to be able to declare an expectation from a selector variable.

I have a class with a method that returns different selectors based on the method parameter: + (SEL)actionForControlEvent:(UIControlEvents)event and I want to declare an expectation from that selector:

UIControlEvents event = UIControlEventTouchDown;
id eventObserverMock = OCMClassMock([ControlEventObserver class]);
SEL selector = [ControlEventObserver actionForControlEvent:event];
OCMExpect([eventObserverMock selector]); //This is not working - (of course)
[ctrl addTarget:eventObserverMock action:selector forControlEvents:event];

Why do I want this? I want to validate the behaviour of custom UIControls

blackivory86 avatar Oct 22 '15 09:10 blackivory86

Not sure what the feature request is. If you want to test the implementation of actionForControlEvent: you don't need a mock at all. Just call the method in your test and make an assertion with your test framework that the returned value is the one you're expecting.

If another class is using actionForControlEvent: then you can stub the method to return the selector value you want.

What am I missing?

erikdoe avatar Oct 22 '15 09:10 erikdoe

Sorry for beeing unclear:

I don't want to test my ControlEventObserver class at all. That's just a helper to verify the behaviour if my custom UIControl.

What I'm trying to do is to verify that my UIControl delivers the expected UIControlEvents to the object that has registered through the [UIControl addTarget:action:forControlEvent:] when it receives Touch-Events. Because we have serveral custom UIControls I want to get rid of a lot of boilerplate code just to set up the expectations. My current idea was to create expectations from a selector which is created by that actionForControlEvent:

My current solution is a huge macro including a switch over the different UIControlEvent types that creates the expectations.

TLDR: If it's possible to create an expectation or stub from a selector that would be great. If nobody else needs that stuff it's nothing of high priority.

blackivory86 avatar Oct 22 '15 09:10 blackivory86

Finally got round to looking into this. It is possible to create an expectation from a selector. To do so you'd have to follow these steps:

  • create an NSInvocation from the selector
  • create an OCMInvocationExpectation and call -setInvocation:
  • optionally call -setRecordedAsClassMethod: and -addInvocationAction:
  • add the expectation to the mock by calling -addStub: and -addExpectation:, both with the expectation isntance as an argument

Unfortunately, this requires several methods that are not in OCMock's public headers.

erikdoe avatar Dec 30 '15 23:12 erikdoe

This could be added to OCMock, maybe by adding a new method to OCClassMockObject such as expectSelector:withArguments:. Then we could define a macro on top of it, maybe something like

OCMExpect(mockObject, selector, arg, ...)

I'll leave this issue open as a feature request.

erikdoe avatar Dec 30 '15 23:12 erikdoe