Potential solution for testing optional methods on protocol mocks where we want to control -respondsToSele… #250
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
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?