iphone - وحدة اختبار لا يمكن العثور على ملف نموذج البيانات الأساسية




cocoa xcode (4)

لقد قمت بإنشاء مشروع مع نموذج البيانات الأساسية في ذلك. التطبيق يبحث عن ملف النموذج (.momd) ويدير على ما يرام.

لسوء الحظ، يبقى اختبار الوحدة عديم القيمة:

NSURL *dataModelURL = [[NSBundle mainBundle] URLForResource:@"myDataModel" withExtension:@"momd"];

أستطيع أن أرى المجلد myDataModel.xdatamodeld والملف في كل من الهدف الرئيسي ودليل تجميع مصادر الهدف اختبار وحدة - ولكن هذا لا يبدو كافيا. ماذا أنا في عداد المفقودين في الهدف اختبار وحدة؟

شكرا، -Luther


الجواب له علاقة مع حزمة. لا يستخدم هدف اختبار الوحدة الحزمة "الرئيسية". أنه يخلق حزمة الخاصة التي، في حالتي، تعثرت إلى 'com.yourcompany.UnitTest' - مباشرة من [الهدف] -info.plist.

ثم يبدو الحل المصحح كما يلي:

NSBundle *bundle = [NSBundle bundleWithIdentifier:@"com.yourcompany.UnitTests"];
NSURL *url = [bundle URLForResource:@"myDataModel" withExtension:@"momd"];

شكر


هذه الطريقة سوف تحصل على الحزمة الخاصة بك من أي هدف. ومع ذلك، لكل الهدف الذي تضيفه، لديك لإضافة يدويا معرف حزمة بليست إلى مجموعة identifiers ، لأنه لا توجد وسيلة للحصول عليه برمجيا. الميزة هي أنه يمكنك استخدام نفس التعليمات البرمجية لاختبار أو تشغيل التطبيق.

+(NSBundle*) getBundle 
{
    NSBundle *bundle = nil;

    // try your manually set bundles
    NSArray *identifiers = [NSArray arrayWithObjects: @"com.your.application",
                                                      @"com.your.test",
                                                      nil];
    for(NSString *bundleId in identifiers) {
        bundle = [NSBundle bundleWithIdentifier:bundleId];
        if (bundle!=nil) break;
    }

    // try the main bundle
    if (bundle==nil) bundle = [NSBundle mainBundle];

    // abort
    assert(bundle!=nil && "Missing bundle. Check the Bundle identifier on 
           the plist of this target vs the identifiers array in this class.");

    return bundle;
}

كان مشكلة مماثلة، أنا حلها باستخدام إطار أوكوك، لذلك لم أكن بحاجة إلى تغيير رمز التطبيق

@interface TestCase()
    @property (nonatomic, strong) id bundleMock;
@end

@implementation TestCase

- (void)setUp
{
    self.bundleMock = [OCMockObject mockForClass:[NSBundle class]];
    [[[self.bundleMock stub] andReturn:[NSBundle bundleForClass:[self class]]] mainBundle];
    [super setUp];
}

- (void)tearDown
{
    [self.bundleMock stopMocking];
    [super tearDown];
}

مشكلتي كانت في الحقيقة الحزمة الخاطئة! كما كنت أحاول استخدام قاعدة بيانات من / ضمن إطار I 'ببساطة' لديه لتحميل ديسيبل من Bundle المقابلة!

هنا هو بعض التعليمات البرمجية في Swift4 باستخدام MagicalRecord :

// Load the bundle
let frameworkBundle = Bundle(for: AClassFromTheFramework.self)
let managedObjectModel = NSManagedObjectModel.mergedModel(from: [frameworkBundle])
// Use the new `managedObjectModel` by default
MagicalRecord.setShouldAutoCreateManagedObjectModel(false)
NSManagedObjectModel.mr_setDefaultManagedObjectModel(managedObjectModel)
// Load the database 
MagicalRecord.setupCoreDataStack(withAutoMigratingSqliteStoreNamed: "db.sqlite")

و فويلا!





ocunit