¿Cómo debo probar el findByAttribute
instance method I added to NSManagedObject
?Prueba Core Data Application
Al principio, pensé en programmatically creating an independent Core Data stack as demonstrated by Xcode's Core Data Utility Tutorial. Y, en mi búsqueda de esa documentación, me encontré con Core Data Fetch Request Templates y pensé que tal vez en lugar de crear el método que hice, debería hacer plantillas de solicitud de recuperación, pero no parece que el entityName
puede ser variable con una plantilla de solicitud de recuperación. ¿puede? ¿Puedo crear una plantilla de solicitud de recuperación en NSManagedObject
para que todas las subclases puedan usarla? Hmm, pero aún necesitaría un entityName
y no creo que haya una manera de obtener dinámicamente el nombre de la subclase que llamó al método.
De todos modos, parece que una buena solución es create an in-memory Core Data stack for testing, independiente de la pila de datos básicos de producción. @Jeff Schilling also recommends creating an in-memory persistent store. Chris Hanson also creates a persistent store coordinator to unit test Core Data. Esto parece similar a cómo Rails tiene una base de datos separada para probar. Pero, @iamleeg recommends removing the Core Data dependence.
¿Cuál crees que es el mejor enfoque? Yo personalmente prefiero lo último.
ACTUALIZACIÓN: Estoy unit testing Core Data with OCHamcrest and Pivotal Lab's Cedar. Además de escribir el código a continuación, agregué NSManagedObject+Additions.m
y User.m
al objetivo Spec
.
#define HC_SHORTHAND
#import <Cedar-iPhone/SpecHelper.h>
#import <OCHamcrestIOS/OCHamcrestIOS.h>
#import "NSManagedObject+Additions.h"
#import "User.h"
SPEC_BEGIN(NSManagedObjectAdditionsSpec)
describe(@"NSManagedObject+Additions", ^{
__block NSManagedObjectContext *managedObjectContext;
beforeEach(^{
NSManagedObjectModel *managedObjectModel =
[NSManagedObjectModel mergedModelFromBundles:nil];
NSPersistentStoreCoordinator *persistentStoreCoordinator =
[[NSPersistentStoreCoordinator alloc]
initWithManagedObjectModel:managedObjectModel];
[persistentStoreCoordinator addPersistentStoreWithType:NSInMemoryStoreType
configuration:nil URL:nil options:nil error:NULL];
managedObjectContext = [[NSManagedObjectContext alloc] init];
managedObjectContext.persistentStoreCoordinator = persistentStoreCoordinator;
[persistentStoreCoordinator release];
});
it(@"finds first object by attribute value", ^{
// Create a user with an arbitrary Facebook user ID.
NSNumber *fbId = [[NSNumber alloc] initWithInteger:514417];
[[NSEntityDescription insertNewObjectForEntityForName:@"User"
inManagedObjectContext:managedObjectContext] setFbId:fbId];
[managedObjectContext save:nil];
NSNumber *fbIdFound = [(User *)[User findByAttribute:@"fbId" value:(id)fbId
entityName:@"User"
inManagedObjectContext:managedObjectContext] fbId];
assertThatInteger([fbId integerValue], equalToInteger([fbIdFound integerValue]));
[fbId release];
});
afterEach(^{
[managedObjectContext release];
});
});
SPEC_END
Si me puede decir por qué si no lo hago me sale cast to (id)
the fbId
argument passed to findByAttribute
warning: incompatible Objective-C types 'struct NSNumber *',
expected 'struct NSString *' when passing argument 2 of
'findByAttribute:value:entityName:inManagedObjectContext:' from
distinct Objective-C type
entonces obtendrá puntos de bonificación! :) Parece que no debería tener que lanzar un NSNumber
a un id
si se supone que el argumento es un id
porque NSNumber
es un id
, ¿verdad?
+1 Una pregunta bien escrita y documentada. Gracias por tomarse el tiempo para componerlo. – TechZen
¡Gracias y de nada! – ma11hew28
¿Qué línea es 47? Sus números de línea no aparecen en el código de la publicación. ;-) – TechZen