【发布时间】:2012-02-08 07:03:52
【问题描述】:
我有一个名为 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);
}
你认为我的单元测试与它有什么关系吗?
【问题讨论】:
-
你使用
NSNumber*来回转换简直是要了我的命!已经直接使用double了! -
好吧,因为这是核心数据,我必须将
latitude、longitude等存储为NSNumber*。但是,我确实尝试过在可能的情况下使用double,但并没有改变结果。
标签: objective-c ios core-data ios5 automatic-ref-counting