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

Potential solution for testing optional methods on protocol mocks where we want to control -respondsToSele… #250

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

carllindberg
Copy link
Contributor

I ran into an issue recently when I wanted to test a class which has a delegate with a number of optional delegate methods. The functionality should be tested for both when the delegate implements an optional method and also when it does not. I could not figure out a way to do this with OCMock other than implementing a slew of individual classes which implement only the desired combination of methods for a particular test, since protocol mocks always return YES from -respondsToSelector: regardless if the method is implemented or not.

The problem is also noted at http://stackoverflow.com/questions/11923942/ocmock-mocking-protocols-with-excluding-optional-methods so it has come up before. The solution there is to create an object which has state which controls the -respondsToSelector: method, and methods to manipulate that state. I ended up with a similar solution, where I made a special class that was designed to be partial mocked, but then knew about the mock counterpart (using private OCMock APIs), and implemented -respondsToSelector: based on if there were any stubs, expects, or rejects on the partial mock. This worked pretty well.

However, I thought of a different though similar approach. This involves a subclass of OCProtocolMockObject instead, which implements -respondsToSelector: for optional methods based on if there are any stubs, expects, or rejects added to the mock. For required methods, it will return YES always. This is basically the same functionality, but seems to fit in more naturally with OCMock. A test can simply expect the methods they want called, and -respondsToSelector: will work for those, but not other methods, allowing to test delegates both ways (implementing methods or not). -reject can be used if the user wants the method to be implemented but still not called. It is not a nice mock, so unexpected calls should still cause exceptions. I'm not sure a "nice" version would make any sense, but it wouldn't to be hard to add if my imagination is just missing something.

Does this approach make sense, or are there better ideas, or is there a way to do this currently that I'm missing?

…ctor:. Problem noted at http://stackoverflow.com/questions/11923942/ocmock-mocking-protocols-with-excluding-optional-methods .  I want to test a class which has a delegate, and the behavior should be tested for situations where the delegate implements an optional method and also when it does not.  I could not figure out a way to do this with OCMock other than implementing a slew of individual classes which implement only the desired combination of methods for a particular test.  This approach is a subclass of OCProtocolMockObject, which implements -respondsToSelector: based on if there are any stubs, expects, or rejects added to the mock.  This way a unit test can control respondsTo status just by manipulating the expects or the stubs.  It is not a nice mock, so unexpected calls should still cause exceptions.  I'm not sure a "nice" version would make any sense, but it wouldn't to be hard to add if my imagination is just missing something.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant