我正试图使用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来进行部分mock。这至少让我可以测试我的代码实现,以确定基于日期和地点的季节。
但是
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;
}