2011-11-25 13 views
6

Ho un'applicazione iOS con dati persistenti utilizzando NSCoding e più precisamente NSKeyedArchiver. Questa applicazione è già disponibile su App Store.Come testare l'unità NSCoding?

Sto lavorando alla versione 2 dell'applicazione e il modello di dati dovrebbe cambiare. Quindi ho bisogno di gestire la migrazione del modello di dati. Lo voglio coperto dai test unitari.

Nei miei test, voglio generare dinamicamente i dati persistenti con il vecchio modello di dati, avviare la migrazione e vedere se tutto è andato bene.

Attualmente, l'archiviazione di un oggetto si presenta così:

MyDataModelObject *object = .... 
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 
[archiver encodeObject:object forKey:key]; 
[archiver finishEncoding]; 

Il problema è, MyDataModelObject potrebbe essere ri-scomposto o addirittura eliminato nella versione 2 dell'applicazione. Quindi non posso usare questa classe nei miei test per generare un 'vecchio archivio delle versioni'.

C'è un modo per simulare ciò che viene fatto nel metodo encodeWithCoder: di una classe senza utilizzare questa classe?


Quello che vorrei realizzare è la seguente

- testMigrationFrom_v1_to_v2 { 
    // simulate an archive with v1 data model 
    // I want this part of the code to be as simple as possible 
    // I don't want to rely on old classes to generate the archive 
    NSDictionary *person = ... // { firstName: John, lastName: Doe } 
    NSDictionary *adress = ... // { street: 1 down street, city: Butterfly City } 
    [person setObject:adress forKey:@"adress"]; 

    // there's something missing to tell the archiever that: 
    // - person is of type OldPersonDataModel 
    // - adress is of type OldAdressDataModel 

    [archiver encodeObject:person forKey:@"somePerson"]; 
    // at this point, I would like the archive file to contain : 
    // a person object of type OldPersonDataModel, that has an adress object of type OldAdressModel 

    NewPersonModel *newPerson = [Migration readDataFromV1]; 

    // assertions 
    NSAssert(newPerson.firstName, @"John"); 
    NSAssert(newPerson.lastName, @"Doe"); 
} 

risposta

1

Non capisco davvero la tua domanda in modo ti darò due risposte:

È possibile precaricare un'istanza di NSDictionary con chiavi/valori che useresti con la tua vecchia classe e crea semplicemente un nuovo archiviatore con chiave, esegui il ciclo di tutte le chiavi e archivialo.

È anche possibile ottenere il metodo -attributeKeys qualsiasi classe per ottenere tutte le chiavi e poi eventualmente utilizzare questo codice per simulare un archivio:

NSKeyedArchiver *archive = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data]; 
[archiver encodeObject:object forKey:key]; 
for (NSString *key in object.attributeKeys) { 
    [archive encodeObject:[object valueForKey:key] forKey:key]; 
} 
[archive finishEncoding]; 

Sul punto di migrazione dei dati, NSKeyedArchiver ha il metodo -setClass:forClassName: e si può supporta tutte le vecchie chiavi nel nuovo oggetto per tradurle in proprietà diverse.

+0

grazie per la risposta, ho modificato la domanda per renderla più chiara (si spera) – David

+1

attributeKeys fa parte di NSClassDescription, che non esiste su iOS. – quellish