- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个名为:ITunesAlbumDataDownloader 的网络类
@implementation AlbumDataDownloader
- (void)downloadDataWithURLString:(NSString *)urlString
completionHandler:(void (^)(NSArray *, NSError *))completionHandler
{
NSURLSession *session = [NSURLSession sharedSession];
NSURLSessionDataTask *dataTask = [session dataTaskWithURL:[NSURL URLWithString:urlString]
completionHandler:^(NSData *data, NSURLResponse *response, NSError *error)
{
NSArray *albumsArray = [self parseJSONData:data];
completionHandler(albumsArray, error);
}];
[dataTask resume];
}
- (NSArray *)parseJSONData:(NSData *)data {
NSMutableArray *albums = [[NSMutableArray alloc] init];
...
...
// Return the array
return [NSArray arrayWithArray:albums];
}
@end
我需要为此创建一个单元测试,它执行以下操作:
//预期的 JSON 响应
NSData *jsonResponse = [self sampleJSONData];
其他要记住的一点是,我需要使用伪造的 JSON 数据“jsonResponse”模拟 NSURLSession 到 downloadDataWithURLString:completionHandler: 方法不调用实际的网络请求。
我尝试了各种不同的方法,但我就是无法解决,我认为这是伪造请求和 block 的结合,这让我很困惑。
这是我尝试过的两个测试方法示例(实际上我也尝试了很多其他方法,但这是我现在剩下的方法):
- (void)testValidJSONResponseGivesAlbumsAndNilError {
// Given a valid JSON response containing albums and an AlbumDataDownloaderTests instance
// Expected JSON response
NSData *jsonResponse = [self sampleJSONDataWithAlbums];
id myMock = [OCMockObject mockForClass:[NSURLSession class]];
[[myMock expect] dataTaskWithRequest:OCMOCK_ANY
completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error)
{
}];
[myMock verify];
}
和
- (void)testValidJSONResponseGivesAlbumsAndNilError {
// Given a valid JSON response containing albums and an AlbumDataDownloaderTests instance
// Expected JSON response
NSData *jsonResponse = [self sampleJSONDataWithAlbums];
id myMock = [OCMockObject mockForClass:[AlbumDataDownloader class]];
[[[myMock stub] andReturn:jsonResponse] downloadDataWithURLString:OCMOCK_ANY
completionHandler:^(NSArray *response, NSError *error)
{
}];
[myMock verify];
}
}
我觉得在这两种情况下我可能都离题了 :(
我非常感谢对此的一些帮助。
谢谢。
更新 1:
这是我现在想到的,但需要知道我是在正确的轨道上还是在犯错误?
id mockSession = [OCMockObject mockForClass:[NSURLSession class]];
id mockDataTask = [OCMockObject mockForClass:[NSURLSessionDataTask class]];
[[mockSession stub] dataTaskWithRequest:OCMOCK_ANY
completionHandler:^(NSData _Nullable data, NSURLResponse Nullable response, NSError * Nullable error)
{
NSLog(@"Response: %@", response);
}];
[[mockDataTask stub] andDo:^(NSInvocation *invocation)
{
NSLog(@"invocation: %@", invocation);
}];
最佳答案
block 的技巧是您需要测试来调用 block ,无论测试需要什么参数。
在 OCMock 中,可以这样做:
OCMStub([mock someMethodWithBlock:([OCMArg invokeBlockWithArgs:@"First arg", nil])]);
这很方便。但…
someMethodWithBlock:
被调用时,该 block 将被立即调用。这通常不能反射(reflect)生产代码的时序。
如果你想推迟调用 block 直到调用方法完成之后,然后捕获它。在 OCMock 中,可以这样做:
__block void (^capturedBlock)(id arg1);
OCMStub([mock someMethodWithBlock:[OCMArg checkWithBlock:^BOOL(id obj) {
capturedBlock = obj;
return YES;
}]]);
// ...Invoke the method that calls someMethodWithBlock:, then...
capturedBlock(@"First arg"); // Call the block with whatever you need
我更喜欢使用 OCHamcrest's HCArgumentCaptor。 OCMock 支持 OCHamcrest 匹配器,所以我相信这应该有效:
HCArgumentCaptor *argument = [[HCArgumentCaptor alloc] init];
OCMStub([mock someMethodWithBlock:argument]);
// ...Invoke the method that calls someMethodWithBlock:, then...
void (^capturedBlock)(id arg1) = argument.value; // Cast generic captured argument to specific type
capturedBlock(@"First arg"); // Call the block with whatever you need
关于objective-c - 使用 NSURLSession 对 OCMock 进行单元测试,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33930577/
我有一个 iOS 应用程序,我正在尝试将 OCMock 添加到其中,以便更好地对其进行单元测试。我已经按照 ocmock.org 上的说明以及我在其他地方找到的说明进行操作,但仍然无法编译我的测试代码
我正在使用 OCMock 来帮助我正在使用 Xcode 为 iPad 应用程序进行的测试驱动开发。我有这样的测试代码: id mock = [OCMockObject mockForProtocol:
在使用 OCMock 框架编写单元测试时,我遇到了一些具体的问题。 假设我有一些带有一个参数的方法。我需要的是 stub 该方法并返回相同的值。该值是计算出来的,所以我不能只通过通常的 stub 返回
我正在尝试为我创建的简单 UIDevice 类别设置一些测试用例。 由于这些方法是实例方法,因此我创建了一个模拟来模拟 currentDevice 行为。 添加的方法基于 name 属性,因此我创建了
我正在使用 OCMock 来测试从 Storyboard 中实例化的 UIViewController。遵循最佳实践, View Controller View 的 subview 的所有 IBOut
我这样设置模拟观察者: id quartileObserverMock = [OCMockObject observerMock]; [[NSNotificationCenter defaultCen
我有一个测试(使用 OCMock)验证在发送特定通知时调用了一个方法: - (void)testThatVCRegistersToLocationUpdateNotification { Is
我想使用 OCMock 这样,无论何时使用任何参数调用 someMethod,它都会调用带有参数“dict”的 callBackMethod:,这是一个 NSDictionary。我找到了 andCa
我一直在使用 OCMock 创建 stub 和模拟。不过,我正在努力模拟本地声明的对象方法。 如果我有下面的代码: // Example.m #import "Object.h" - (NSStrin
我做了一个部分模拟,一个测试按预期运行,但对于第二个测试,它连续调用 setUp 和 teardown 而没有调用实际测试。 - (void)setUp { [super setUp]; _r
我正在尝试在我们的大型项目中设置一些单元测试。问题是某些 ViewController 在调用部分模拟崩溃时会出现以下跟踪: error: -[EspionageViewControllerTests
当我们用OCMock创建一个模拟对象时,例如 id classMock = OCMClassMock([SomeClass class]); classMock 是后台 SomeClass 的真实对象
我正在加快使用 OCMock 模拟 iOS 的速度。我写了一个简单的模拟单元测试,当它应该失败时——基于我设定的期望——它会通过。 代码如下: // Scientific Calculator cla
我正在尝试模拟一个类方法来识别 iOS 是 iOS 6(或更早版本)还是 iOS 7(或更高版本)。这是测试代码: id iOSDetectorMock = [OCMockObject mockFor
这是一个关于 OCMock 期望的极其基本的问题。让我们在 objectA 上有一个实例方法 methodA,它调用 objectA 上的实例方法 methodB。 - (void)methodA {
我有一个如下签名的方法; - (NSInteger) getFirstVisitTimeStamp; 当我使用 OCMock 模拟并返回一个值时,测试失败并出现以下错误。 [[[[YSNYI13NMo
我终于将一些 TDD 强加到我正在从事的项目中,并且遇到了边缘......我知道我想要的代码但不知道如何测试它:) 我正在寻找的实现是: - (void) doSomething { FooB
我是新来的 OCMock . 我使用 dispatch_once() 创建了一个单例类 MyManager : @implementation MyManager + (id)sharedInstan
我正在尝试为输出取决于 NSDate 的 timeIntervalSinceNow 返回值的方法编写测试。我想在我的测试中指定返回值,以便我可以测试某些场景。 我很难让这个 OCMock 对象返回我想
我是 OCMock 的新用户,所以我可能只是遗漏了一些简单的东西。此代码无法编译: id mockSession = [OCMockObject mockForClass:[AVCaptureSess
我是一名优秀的程序员,十分优秀!