I am learning OCMock for iOS testing. What's the difference between "class mock" and "partial mock", and when should you use one vs the other?
iOS OCMock partial vs class mock
Class mocks
create objects that are pure mocks of a class instance.
Partial mocks
take an instance of a class an allow you to stub any of its methods.
Suppose I have these classes:
@interface Foo : NSObject
- (void)doX;
@end
@implementation
- (void)doX
{
NSLog(@"X");
}
@end
@interface Bar : NSObject
- (void)doA:(Foo *)foo;
- (void)doB;
@end
@implementation Bar
- (void)doA:(Foo *)foo
{
NSLog(@"A");
[foo doX];
[self doB];
}
- (void)doB
{
NSLog(@"B");
}
@end
I'm interested in testing Bar's doA:
method. I expect it to call doX
on a Foo
object, then to call its own doB
method. I would implement this using a class mock of a Foo and a partial mock of a Bar.
- (void)test_doA_shouldCall_doX_and_doB
{
id objectUnderTest = [OCMockObject partialMockForObject:[Bar new]];
id fooMock = [OCMockObject mockForClass:Foo.class];
[[fooMock expect] doX];
[[objectUnderTest expect] doB];
// Make the call
[objectUnderTest doA:fooMock];
[objectUnderTest verify];
[fooMock verify];
}
You see here that my partial mock allowed me to call the real method I wanted to test while mocking an internal call to another of its instance methods. Because I didn't need any of the real functionality of Foo, however, I used a class mock.
Thanks for the really helpful answer. I have two followup questions: 1) Is it true that pure mocks do not allow you to call any real methods? 2) Why couldn't you create a partial mock of Foo and then do an expect on the doX method? –
Disequilibrium
1. A pure mock isn't backed by a real object, but technically you can set up any mock to call any method by using
andCall
or andDo
-- a partial mock allows you to do andForwardToRealObject
. 2. You could create a partial mock of Foo -- sometimes the creation of an object either has side effects or involves work irrelevant to your test. Additionally, a pure mock that is not a nice mock will complain when an unexpected method is called whereas a partial mock will not. –
Killigrew © 2022 - 2024 — McMap. All rights reserved.