I have a pretty simple setup for this unit test. I have a class that has a delegate property:
@interface MyClass : NSObject
...
@property (nonatomic, weak) id<MyDelegateProtocol> connectionDelegate;
...
@end
and I set the delegate in my test:
- (void)testMyMethod_WithDelegate {
id delegate = mockDelegateHelper(); // uses OCMock to create a mock object
[[delegate expect] someMethod];
myClassIvar.connectionDelegate = delegate;
[myClass someOtherMethod];
STAssertNoThrow([delegate verify], @"should have called someMethod on delegate.");
}
But the delegate is not actually set on line 3 of my unit test, so #someMethod is never called. When I change it to
myClassIvar.connectionDelegate = delegate;
STAssertNotNil(myClassIvar.connectionDelegate, @"delegate should not be nil");
it fails there. I'm using ARC, so my hunch was that the weak property was being deallocated. Sure enough, changing it to strong
makes the STAssertNotNil
pass. But I don't want to do that with a delegate, and I don't understand why that makes a difference here. From what I've read, all local references in ARC are strong
, and STAssertNotNil(delegate)
passes. Why is my weak delegate property nil when the same object in a local variable is not?
Self-validating means that a test should perform operations and programmatically check for the result. For instance, if you're testing that you've written something on a file, the test itself is in charge of checking that it worked correctly. No manual operations should be done.
A unit can be almost anything you want it to be -- a line of code, a method, or a class. Generally though, smaller is better. Smaller tests give you a much more granular view of how your code is performing.
Unit testing provides documentationTo learn what functionality is provided by one module or another, developers can refer to unit tests to get a basic picture of the logic of the module and the system as a whole.
Unit testing is a software development process in which the smallest testable parts of an application, called units, are individually and independently scrutinized for proper operation. This testing methodology is done during the development process by the software developers and sometimes QA staff.
This is a bug in the iOS runtime. The following discussion has more detail. In a nutshell, the iOS ARC runtime can't seem to handle weak references to proxies. The OSX runtime can.
http://www.mulle-kybernetik.com/forum/viewtopic.php?f=4&t=252
As far as I understand from the discussion a bug report has been filed with Apple. If anyone has a sensible idea for a workaround...
I don't really know what's happening here, but OCMock returns an autoreleased NSProxy
-descendant from the mockForProtocol:
method, which I think is right. Maybe ARC has problems with NSProxies? Anyway, I've overcome this problem by declaring the variable __weak
:
- (void)testMyMethod_WithDelegate {
// maybe you'll also need this modifier inside the helper
__weak id delegate = mockDelegateHelper();
...
It really doesn't need to be __strong
(the default) in this case, as it's autoreleased and you're not keeping it around...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With