3

我正在尝试使用 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;
    }
}

我可以通过使用一个类别来暴露currentMonthcurrentLatitude方法来测试上面的公共方法,然后使用OCMock进行部分模拟。这至少让我可以测试我的代码实现,以根据日期和位置计算出季节。

1) 对我来说,使用类别扩展来有效地将两个私有方法变为公共方法似乎是一种代码味道。2)这不是测试我是否正确获取位置。

那么我将如何编码,以便我可以测试我是否正确获取当前位置?我的意思是,这里最好的方法是使用不同的指定 init 方法来接受 a 的实例CLLocationManager。这可能是一个模拟实例,或者当代码在生产中运行时的真实实例?此外,该currentSeason方法是否应该更改为类似currentSeasonForDate:NSDate

4

1 回答 1

1

这类问题的传统解决方案是依赖注入,它有助于推动关注点分离。的工作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;
}
于 2013-07-01T12:35:30.533 回答