Основные данные: пользовательский установщик, который не выполняет каскадный расчет - PullRequest
1 голос
/ 12 января 2012

У меня есть класс с именем 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

Что я делаю не так?

UNIT TEST

Вот моя функция, которую я использую для сохранения контекста в модульном тесте,

- (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);
}

Как вы думаете, мой модульный тест имеет какое-либо отношение к нему?

1 Ответ

1 голос
/ 12 января 2012

Я заметил, что ваш метод создает переменные с именем radLat, но это также свойство вашего экземпляра - я чувствую, что у вас могут возникнуть проблемы с указателями.

Попробуйте изменить имя переменных вашего метода (double radLat и т. Д.) На что-то другое и посмотрите, изменится ли это как ваш код.Я думаю, что код работает не так, как вы ожидаете, хотя знание кода, работающего в вашем классе Location, поможет.

...