2016-06-19 64 views
1

背景設計一個Objective-C類是可測試

我與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]; 
} 

回答

2

一對夫婦需要考慮的事情:

  • 在我看來,設計iOS代碼(Objective-C或Swift)與在Java中設計代碼沒有什麼不同。同樣的原則適用,你會以同樣的方式做到這一點。

  • 儘可能避免單身人士。例如,您仍然可以在該類上有一個訪問器來返回您的服務,但也有一個可以清除,重置或注入新實例的方法。純粹的單身模式是測試後端的痛處,單身人士在許多iOS項目中經常過度使用。在我的代碼中,儘管我可以編寫單例代碼,但我通常也可以將它們設置爲(即使僅來自單元測試源代碼中的類別)。

  • 調查OCMock Objective-C嘲諷框架。我已經使用了很多年了,而且它很少做不到。非常類似於像Easymock和Mockito這樣的Java框架。但請注意,如果您正在考慮使用Swift,那麼對Swift的嘲笑幾乎是不存在的。 Swift根本沒有運行時功能。

0

「這個問題似乎是一個合理的辦法?」是的(雖然我們不知道你的測試旨在證明什麼,或者你的其他代碼如何使用這個類)。

顯然還有其他選擇,例如使用子類來啓用附加的可測試性。這樣做的好處是,您不會將用戶公開地聲明爲單例類和實例類。

想想也是單身是否真的適合你的方法 - 你是否希望能夠重用這個類有不同的會話 - 以及是否工廠的做法會更好......

+0

Thanks @ josh-caswell剛剛檢查了拼寫錯誤的含義:-S – Wain

+0

呵呵,我甚至都不知道這是一個字! :) –