如何对 NSCoding 进行单元测试?

Posted

技术标签:

【中文标题】如何对 NSCoding 进行单元测试?【英文标题】:How to unit test NSCoding? 【发布时间】:2011-11-25 09:27:27 【问题描述】:

我有一个使用 NSCoding 更准确地说是 NSKeyedArchiver 保存数据的 ios 应用程序。此应用程序已在 App Store 上架。

我正在开发应用程序的第 2 版,并且数据模型应该更改。所以我需要处理数据模型迁移。我希望它被单元测试覆盖。

在我的测试中,我想使用旧数据模型动态生成持久化数据,启动迁移并查看是否一切顺利。

目前,归档对象如下所示:

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

问题是,MyDataModelObject 可能在应用程序的版本 2 中被重构甚至删除。所以我不能在我的测试中使用这个类来生成一个“旧版本存档”。

有没有办法在不使用此类的情况下模拟类的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: 方法,您可以支持新对象中的所有旧键,以将它们转换为不同的属性。

【讨论】:

感谢您的回答,我编辑了问题以使其更清楚(希望如此) attributeKeys 是 NSClassDescription 的一部分,iOS 上不存在。

以上是关于如何对 NSCoding 进行单元测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何对 ETL 流程进行测试(单元测试)?

如何在订阅Angular7单元测试用例中对代码进行单元测试

如何对抽象类进行单元测试

如何对 Excel VBA 代码进行单元测试

如何对 WCF 服务进行单元测试?

如何对私有 Cocoapods 库进行单元测试?