I am working on unit tests using XCTest and OCMock 2.2.1. I have a class that obtains the bundle identifier using:
NSString *bundleIdentifier = [[NSBundle bundleForClass:[self class]] bundleIdentifier];
This works as expected while running the application or the unit tests for this class in particular.
While working through tests on other classes, I am partially mocking this object but still require the method that gets the bundle identifier to run.
What I am seeing is prior to passing the instance of the object to + [OCMockObject partialMockForObject:]
looks correct:
(lldb) po myObject
<MyObject: 0x1006ec480>
(lldb) po [NSBundle bundleForClass:[myObject class]]
NSBundle </Users/paynerc/Library/Developer/Xcode/DerivedData/xxxx/Build/Products/Debug/MyTests Tests.xctest> (loaded)
(lldb) po [[NSBundle bundleForClass:[myObject class]] bundleIdentifier]
com.paynerc.MyBundle
However, after I pass myObject
into [OCMockObject partialMockForObject:myObject]
, things change:
(lldb) po myObject
<MyObject-0x1006ec480-401894396.880136: 0x1006ec480>
(lldb) po [NSBundle bundleForClass:[myObject class]]
NSBundle </Applications/Xcode.app/Contents/Developer/usr/bin> (loaded)
(lldb) po [[NSBundle bundleForClass:[myObject class]] bundleIdentifier]
nil
The fact that the object is modified and includes the partial mock magic makes sense. What doesn't seem to make sense is why the call to bundleForClass
has changed what it returns.
Is there anything I can do to ensure that bundleForClass
continues to return the original value, short of mocking the calls inside MyObject? The concern there is that anybody else that needs a partial mock of MyObject in another unit test will need to remember to provided a stubbed implementation of bundleForClass
.
My present solution is to request the bundle identifier and examine the result. If it is nil, I am calling [NSBundle allBundles]
and iterating over them until I find one that has a non-nil bundleIdentifier. While that currently... works... it's A) not very robust B) horribly brute force-ish and C) modifying application code to support unit tests.
Has anybody else come across this and come up with a better solution?