Как провести юнит-тестирование NSCoding?
У меня есть приложение iOS с данными, сохраненными с использованием NSCoding и, точнее, NSKeyedArchiver. Это приложение уже доступно в App Store.
Я работаю над версией 2 приложения, и модель данных должна измениться. Поэтому мне нужно обработать миграцию модели данных. Я хочу, чтобы это покрывалось юнит-тестами.
В своих тестах я хочу динамически генерировать постоянные данные со старой моделью данных, запускать миграцию и проверять, все ли прошло хорошо.
В настоящее время архивация объекта выглядит следующим образом:
MyDataModelObject *object = ....
NSKeyedArchiver *archiver = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
[archiver encodeObject:object forKey:key];
[archiver finishEncoding];
Проблема в том, что MyDataModelObject может быть повторно проанализирован или даже удален во второй версии приложения. Поэтому я не могу использовать этот класс в своих тестах для создания "архива старой версии".
Есть ли способ имитировать то, что делается в encodeWithCoder:
метод класса без использования этого класса?
Я хотел бы добиться следующего
- 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");
}
1 ответ
Я не очень понимаю ваш вопрос, поэтому я дам вам два ответа:
Вы можете предварительно загрузить экземпляр NSDictionary
с ключами / значениями, которые вы используете со своим старым классом, и просто создайте новый архиватор с ключами, пройдитесь по всем ключам и заархивируйте его.
Вы также можете получить любой класс -attributeKeys
метод, чтобы получить все ключи, а затем, возможно, использовать этот код для имитации архива:
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];
В момент переноса данных в NSKeyedArchiver есть метод -setClass:forClassName:
и вы можете поддерживать все ваши старые ключи в вашем новом объекте, чтобы перевести их в различные свойства.