我有一个非常简单的单元测试设置。我有一个具有委托属性的类:
@interface MyClass : NSObject
...
@property (nonatomic, weak) id<MyDelegateProtocol> connectionDelegate;
...
@end
我在测试中设置了委托:
- (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.");
}
但是代理实际上并没有设置在我的单元测试的第3行,所以#someMethod永远不会被调用。当我将其更改为
时myClassIvar.connectionDelegate = delegate;
STAssertNotNil(myClassIvar.connectionDelegate, @"delegate should not be nil");
它失败了。我使用ARC,所以我的预感是弱房产被解除分配。当然,将其更改为strong
会使STAssertNotNil
通过。但我不想与代表那样做,而且我不明白为什么这会有所作为。根据我的阅读,ARC中的所有本地参考都是strong
,STAssertNotNil(delegate)
通过。当局部变量中的同一对象不是时,为什么我的弱委托属性为nil?
答案 0 :(得分:8)
这是iOS运行时中的一个错误。以下讨论有更多细节。简而言之,iOS ARC运行时似乎无法处理对代理的弱引用。 OSX运行时可以。
http://www.mulle-kybernetik.com/forum/viewtopic.php?f=4&t=252
据我所知,从讨论中已经向Apple提交了一份错误报告。如果有人对解决方法有明智的想法......
答案 1 :(得分:4)
我真的不知道这里发生了什么,但是OCMock从mockForProtocol:
方法返回一个自动释放的NSProxy
- 后代,我认为是正确的。也许ARC有NSProxies的问题?无论如何,我通过声明变量__weak
:
- (void)testMyMethod_WithDelegate {
// maybe you'll also need this modifier inside the helper
__weak id delegate = mockDelegateHelper();
...
在这种情况下,它确实不需要是__strong
(默认值),因为它是自动释放的,而且你不会保留它......
答案 2 :(得分:2)
解决方法是使用Partial Mocks。
@interface TestMyDelegateProtocolDelegate : NSObject <MyDelegateProtocol>
@end
@implementation TestMyDelegateProtocolDelegate
- (void)someMethod {}
@end
@implementation SomeTest {
- (void)testMyMethod_WithDelegate {
id<MyDelegateProtocol> delegate = [[TestMyDelegateProtocolDelegate] alloc] init];
id delegateMock = [OCMockObject partialMockForObject:delegate]
[[[delegateMock expect] someMethod]
myClassIvar.connectionDelegate = delegate;
[myClass someOtherMethod];
STAssertNoThrow([delegate verify], @"should have called someMethod on delegate.");
}
@end
答案 3 :(得分:1)
我不是ARC专家,但我的猜测是mockDelegateHelper()
正在返回一个弱对象。因此,delegate
在第二行代码执行之前为零。我冒昧地猜测,mockDelegateHelper()
是罪魁祸首,或者OCMock正在阻碍它操纵和创建对象的方式。