[英]Best Practice for mocking system date and Location in Objective C unit tests
我正在嘗試使用TDD方法在Objective C中編寫一個類。 該類基本上應該實現該協議。
@protocol SeasonService <NSObject>
-(t_Season)currentSeason;
@end
t_Season
只是冬季,春季,夏季和秋季的一個枚舉。
假設我有一個實現上述偽代碼的類
@implementation SeasonServiceImpl
- (t_Season)currentSeason
{
// Get Date
int month = [self currentMonth];
// Get Latitude
float latitude = [self currentLatitude];
// work out the season based on month and latitude
// (i.e, Northern or Southern hemisphere)
return season;
}
}
我可以通過使用類別來公開currentMonth
和currentLatitude
方法來測試上面的公共方法,然后使用OCMock進行局部模擬。 至少讓我測試我的代碼實現,以確定它是基於日期和位置的季節。
但
1)對我來說,使用類別擴展來有效地將兩個私有方法轉換為公共方法似乎是一種代碼氣味。 2)它沒有測試我是否正確獲取位置。
那么我將如何對此進行編碼以便我可以測試我是否正確獲取當前位置? 我的意思是,這是最好的方法,有一個不同的指定init方法,它接受一個CLLocationManager
的實例。 那可能是一個模擬的實例,或者是代碼在生產中運行的真實實例? 此外, currentSeason
方法是否應該更改為currentSeasonForDate:NSDate
?
這種問題的傳統解決方案是依賴注入 ,它有助於推動關注點分離 。 SeasonService
的工作是根據緯度和月份確定它是什么季節。 確定/存儲緯度和月份應該應該是其他類的責任。
根據系統的要求,可以通過構造參數或方法參數來實現。 無論哪種方式,您都可以直接模擬特定月份或緯度,而不是訴諸類別技巧。
構造函數注入:
- initWithLatitudeProvider:id<LatitudeProvider> latitudeProvider
andMonthProvider:id<MonthProvider> monthProvider {
// set ivars or properties
}
- (t_Season)currentSeason
{
// Get Date
int month = [[self monthProvider] currentMonth];
// Get Latitude
float latitude = [[self latitudeProvider] currentLatitude];
// work out the season based on month and latitude
// (i.e, Northern or Southern hemisphere)
return season;
}
或方法參數注入:
- (t_Season)currentSeasonAtLatitude:(float)latitude inMonth:(int)month
{
// work out the season based on month and latitude
// (i.e, Northern or Southern hemisphere)
return season;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.