gpt4 book ai didi

ios - CLLocationManagerDelegate 模拟用户拒绝

转载 作者:行者123 更新时间:2023-11-29 12:58:39 24 4
gpt4 key购买 nike

-- 最终编辑:更准确的问题Unit Test CLLocationManager implementation

我正在尝试模拟 CLLocationManagerDelegate 来处理用户对地理定位的拒绝

id locationManager = [OCMockObject niceMockForClass:[CLLocationManager class]];
[[[locationManager stub] andReturnValue:@(kCLAuthorizationStatusDenied)] authorizationStatus];

id delegateTarget = [OCMockObject niceMockForProtocol:@protocol(CLLocationManagerDelegate)];
[[delegateTarget expect] locationManager:locationManager didFailWithError:[OCMArg any]];

[locationManager setDelegate:delegateTarget];
[locationManager startUpdatingLocation];

[delegateTarget verify];

但是这段代码不起作用,我一直收到这个错误:

Name: NSInternalInconsistencyException File: Unknown Line: Unknown Reason: OCMockObject[CLLocationManagerDelegate]: expected method was not invoked: locationManager:OCMockObject[CLLocationManager] didFailWithError:

我如何确定 CLLocationManagerDelegate 方法 locationManager:didFailWithError: 被调用了?

编辑:如果我对 CLLocationManager 实例使用 partialMock 而不是 niceMock:

CLLocationManager *trueLocationManager = [[CLLocationManager alloc] init];
id locationManager = [OCMockObject partialMockForObject:trueLocationManager];
[[[locationManager stub] andReturnValue:@(kCLAuthorizationStatusDenied)] authorizationStatus];

id delegateTarget = [OCMockObject mockForProtocol:@protocol(CLLocationManagerDelegate)];
[[delegateTarget expect] locationManager:trueLocationManager didFailWithError:[OCMArg any]];

[locationManager setDelegate:delegateTarget];
[locationManager startUpdatingLocation];

[delegateTarget verify];

我明白了:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'OCMockObject[CLLocationManagerDelegate]: unexpected method invoked: locationManager: didChangeAuthorizationStatus:2 expected: locationManager: didFailWithError:'

所以我想我明白了,并在我的 delegateTarget 期望 didFailWithError 之前添加了下面的代码

[[delegateTarget expect] locationManager:trueLocationManager didChangeAuthorizationStatus:2]; // kCLAuthorizationStatusDenied = 2

结果是:

Name: NSInternalInconsistencyException File: Unknown Line: Unknown Reason: OCMockObject[CLLocationManagerDelegate] : 2 expected methods were not invoked: locationManager: didChangeAuthorizationStatus:2 locationManager: didFailWithError:

真的不知道我做错了什么......

编辑 2:对于 Ilea Cristian

CLLocationManager *trueLocationManager = [[CLLocationManager alloc] init];
id locationManager = [OCMockObject partialMockForObject:trueLocationManager];
[[[locationManager stub] andReturnValue:@(kCLAuthorizationStatusDenied)] authorizationStatus];

id delegateTarget = [OCMockObject mockForProtocol:@protocol(CLLocationManagerDelegate)];
[[delegateTarget expect] locationManager:locationManager didChangeAuthorizationStatus:2]; // kCLAuthorizationStatusDenied = 2
[[delegateTarget expect] locationManager:locationManager didFailWithError:[OCMArg any]];

[locationManager setDelegate:delegateTarget];
[locationManager startUpdatingLocation];

[delegateTarget verify];

我明白了:

Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'OCMockObject[CLLocationManagerDelegate]: unexpected method invoked: locationManager: didChangeAuthorizationStatus:2 expected: locationManager:OCPartialMockObject[CLLocationManager] didChangeAuthorizationStatus:2 expected: locationManager:OCPartialMockObject[CLLocationManager] didFailWithError:'

看起来委托(delegate)回调中使用的 locationManager 是 trueLocationManager 而不是 locationManager (partialMock)

-- 最终编辑:更准确的问题Unit Test CLLocationManager implementation

最佳答案

你有这一行:

[locationManager setDelegate:delegateTarget];

这意味着当调用 locationManager:didFailWithError: 时,为 CLLocationManager 参数传递的对象将是名为 locationManager 的 OCMock 对象> - 而不是 trueLocationManager

您的期望:

[[delegateTarget expect] locationManager:trueLocationManager didFailWithError:[OCMArg any]];

因此,您期待一个传递 trueLocationManager 的调用,但传递的是部分模拟。尝试期望部分模拟通过。

OCMock 部分模拟,如 locationManager,只是对真实对象的代理包装,但它们的类型不同(这就是为什么你使用 id 而不是真实类型)。

之所以如此神奇,是因为 Objective-C 通过消息传递处理调用的方式。如果你阅读了一些关于 NSProxy 的内容然后你看看 OCMock implementation您将真正了解一些后台工作的工作原理。

编辑:

我个人不知道你到底想测试什么。苹果框架?那里的实体都不是你的类/协议(protocol)。你在测试什么?

我猜你有一个实现 CLLocationManagerDelegate 协议(protocol)的 ViewController。 mock 那个类(class)。如果您的位置管理器是一个属性,则将其 stub 以返回您的假位置管理器(以便 vc 在内部使用假的)。或者将假的 locationManager.delegate 设置为您的 ViewController。启动假位置管理器。

期望调用 ViewControllers 委托(delegate)方法。如果您的位置管理器是单例,那么 it's a bit tricky to replace it用假的/ stub 。

关于ios - CLLocationManagerDelegate 模拟用户拒绝,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20348121/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com