核心数据:执行级联计算失败的自定义设置程序



我有一个名为Location的类,它具有以下自动生成的声明,

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>
@interface Location : NSManagedObject
@property (nonatomic, retain) NSNumber * cosRadLat;
@property (nonatomic, retain) NSNumber * latitude;
@property (nonatomic, retain) NSNumber * longitude;
@property (nonatomic, retain) NSNumber * radLat;
@property (nonatomic, retain) NSNumber * radLng;
@property (nonatomic, retain) NSNumber * sinRadLat;
@end

在objective-c类别中,我创建了两种基于纬度和经度计算其他属性的方法,

- (double)degreesToRadians:(NSNumber *)degrees
{
    double radians = ([degrees doubleValue] * M_PI) / 180.0;
    return radians;
}
- (void)setLatitude:(NSNumber *)newLat longitude:(NSNumber *)newLng
{
    [self setLatitude:newLat];
    [self setLongitude:newLng];
    // Make calculations
    double dblRadLat = [self degreesToRadians:newLat];
    double dblRadLng = [self degreesToRadians:newLng];
    double dblCosRadLat = cos(dblRadLat);
    double dblSinRadLat = sin(dblRadLat);
    // and set their values
    [self setRadLat:[NSNumber numberWithDouble:dblRadLat]];
    [self setRadLng:[NSNumber numberWithDouble:dblRadLng]];
    [self setCosRadLat:[NSNumber numberWithDouble:dblCosRadLat]];
    [self setSinRadLat:[NSNumber numberWithDouble:dblSinRadLat]];
}

当我运行我的单元测试时,一半的时间我会得到这个:

Lat 40.7302133
Lng -74.0003337
RadLat 0.7108763271245849
RadLng -1.291549470639518
CosRadLat 0.7577903652576623
SinRadLat 0.6524980937310535

另一半,我得到了这个:

Lat 40.7302133
Lng -74.0003337
RadLat 0
RadLng 0
CosRadLat 0
SinRadLat 0

我做错了什么?

单元测试

这是我用来保存单元测试中上下文的函数,

- (void)saveContext
{
    NSLog(@"%@ saveContext", self.name);
    NSError *saveError = nil; 
    STAssertTrue([self.managedObjectContext save:&saveError], @"Failed to save context to persistent store: %@", saveError);
}

以下是我对它的称呼,

// Constants we will check to ensure our calcluations are correct
// 1st Location
double const LAT = 40.7292540;
double const LNG = -73.9988530;
double const RAD_LAT = 0.710859584;
double const RAD_LNG = -1.29152363;
double const SIN_RAD_LAT = 0.652485406;
double const COS_RAD_LAT = 0.75780129;
double const accuracy = 0.00000001;
/** Run before each test. Populates the database with objects to play with.
 */
- (void)setUp
{
    NSLog(@"%@ setUp", self.name);
    // Creates our persistent store in memory and initializes our managed object context for us.
    [super setUp];
    // Create a new Location
    Location *location = [NSEntityDescription insertNewObjectForEntityForName:@"Location" inManagedObjectContext:self.managedObjectContext];
    // Using the setLatitude:longitude: method, which cascades the calculation for all other values
    [location setLatitude:[NSNumber numberWithDouble:LAT] longitude:[NSNumber numberWithDouble:LNG]];
    // Check if it has properly calculated the values we asked for
    double lat = [[location latitude] doubleValue];
    double lng = [[location longitude] doubleValue];
    double rad_lat = [[location radLat] doubleValue];
    double rad_lng = [[location radLng] doubleValue];
    double sin_rad_lat = [[location sinRadLat] doubleValue];
    double cos_rad_lat = [[location cosRadLat] doubleValue];
    STAssertEqualsWithAccuracy(LAT, lat, accuracy, @"Wanted: %f Got: %f", LAT, lat);
    STAssertEqualsWithAccuracy(LNG, lng, accuracy, @"Wanted: %f Got: %f", LNG, lng);
    STAssertEqualsWithAccuracy(RAD_LAT, rad_lat, accuracy, @"Wanted: %f Got: %f", RAD_LAT, rad_lat);
    STAssertEqualsWithAccuracy(RAD_LNG, rad_lng, accuracy, @"Wanted: %f Got: %f", RAD_LNG, rad_lng);
    STAssertEqualsWithAccuracy(SIN_RAD_LAT, sin_rad_lat, accuracy, @"Wanted: %f Got: %f", SIN_RAD_LAT, sin_rad_lat);
    STAssertEqualsWithAccuracy(COS_RAD_LAT, cos_rad_lat, accuracy, @"Wanted: %f Got: %f", COS_RAD_LAT, cos_rad_lat);
    // Saves the managed object context into the persistent store.
    [self saveContext];
}

这部分通常有效。发生的情况是,调用setup,它运行这个测试,这里是它失败的地方,

- (Location *)fetchLastLocation
{
    NSLog(@"%@ getLastLocation", self.name);
    NSMutableArray *mutableFetchResults = [self fetchEntity: @"Location"];
    Location *location = (Location *)[mutableFetchResults lastObject];
    return location;
}
/** Tests to see if the values stick after saving and fetching
 */
- (void)testCalculatedValuesStick
{
    Location *location = [self fetchLastLocation];
    NSLog(@"Stick: %@", location);
    // Check if it has properly calculated the values we asked for
    double lat = [[location latitude] doubleValue];
    double lng = [[location longitude] doubleValue];
    double rad_lat = [[location radLat] doubleValue];
    double rad_lng = [[location radLng] doubleValue];
    double sin_rad_lat = [[location sinRadLat] doubleValue];
    double cos_rad_lat = [[location cosRadLat] doubleValue];
    STAssertEqualsWithAccuracy(LAT, lat, accuracy, @"Wanted: %f Got: %f", LAT, lat);
    STAssertEqualsWithAccuracy(LNG, lng, accuracy, @"Wanted: %f Got: %f", LNG, lng);
    STAssertEqualsWithAccuracy(RAD_LAT, rad_lat, accuracy, @"Wanted: %f Got: %f", RAD_LAT, rad_lat);
    STAssertEqualsWithAccuracy(RAD_LNG, rad_lng, accuracy, @"Wanted: %f Got: %f", RAD_LNG, rad_lng);
    STAssertEqualsWithAccuracy(SIN_RAD_LAT, sin_rad_lat, accuracy, @"Wanted: %f Got: %f", SIN_RAD_LAT, sin_rad_lat);
    STAssertEqualsWithAccuracy(COS_RAD_LAT, cos_rad_lat, accuracy, @"Wanted: %f Got: %f", COS_RAD_LAT, cos_rad_lat);
}

你认为我的单元测试与此有关吗?

我注意到你的方法正在生成名为radLat的变量,但这也是你的实例的一个属性——我觉得你可能会遇到指针问题。

尝试将方法变量(double radLat等)的名称更改为不同的名称,看看这是否会改变代码的运行方式。我认为代码的行为并不像您期望的那样——尽管了解更多关于Location类上操作的代码会有所帮助。

最新更新