背景
我主要使用Java。这是我在Objective-C中编写的一些代码。我的目标是为“MyService”编写一些单元测试。仅供参考:此代码中类的名称只是占位符。
问题
这看起来像是一种合理的方法吗?我是:
sharedMyService
)NSURLSession
NSURLSession
我的意图是:
NSURLSession
NSURLSession
模拟注入此类来测试它dataTaskWithURL:
方法。这是头文件:
#import <Foundation/Foundation.h>
@interface MyService : NSObject
@property(nonatomic, strong, readwrite) NSURLSession *session;
+ (id)sharedMyService;
- (instancetype)initWithURLSession:(NSURLSession *)session;
- (void)fetchData:(NSString*)location;
@end
实施......
#import "MyService.h"
@implementation MyService
static NSString *const targetUri = @"http://something.com/%@";
+ (instancetype)sharedMyService {
static MyService *service = nil;
@synchronized (self) {
if (service == nil) {
service = [[self alloc] init];
}
}
return service;
}
- (instancetype)initWithURLSession:(NSURLSession *)session {
self = [super init];
if (self) {
self.session = session;
}
return self;
}
- (instancetype)init {
return [self initWithURLSession:[NSURLSession sharedSession]];
}
- (NSURLSession *)getSession {
return self.session;
}
- (void)fetchData:(NSString*)location {
NSURL *targetUrl = [NSURL URLWithString:[NSString stringWithFormat:targetUri, location]];
NSURLSession *urlSession = [self getSession];
NSURLSessionTask *sessionTask = [urlSession dataTaskWithURL:targetUrl completionHandler: ^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
NSLog(@"Request succeeded.");
}];
[sessionTask resume];
}
答案 0 :(得分:2)
要考虑的几件事情:
在我看来,设计iOS代码(Objective-C或Swift)与使用Java设计代码没有什么不同。同样的原则也适用,你也可以这样做。
尽可能避免单身人士。例如,您仍然可以在类上拥有一个访问器来返回您的服务,但也有一个方法可以清除,重置或注入新实例。纯单一模式是测试后端的一个难点,单身人士经常在许多iOS项目中过度使用。在我的代码中,即使我可以编写单例代码,我通常也可以将它们设置为可设置(即使只是来自单元测试源代码中的类别)。
查看OCMock Objective-C模拟框架。我已经使用了很多年,而且它几乎无法做到。与Easymock和Mockito等Java框架非常相似。请注意,如果您正在考虑使用Swift,那么Swift的模拟几乎不存在。 Swift根本没有运行时功能。
答案 1 :(得分:0)
&#34;这看起来像是一种合理的做法吗?&#34;是(虽然我们不知道您的测试旨在证明什么,或者您的其他代码将如何使用此类)。
显然还有其他选项,例如使用子类来实现额外的可测试性。这样做的好处是,您不会通过公开将该类声明为单例和可实例化的类来混淆用户。
还要考虑一个单身人士是否真的适合你 - 你是否希望能够在不同的会话中重复使用这个课程 - 以及工厂方法是否会更好......