2015-05-15 20 views
9

Tôi cần kiểm tra đơn vị (XCTest) một số phương pháp của tôi bao gồm tham chiếu đến các mô hình CoreData.swift - Kiểm tra đơn vị Mô hình CoreData (+ MagicalRecord) kích hoạt EXC_BAD_ACCESS

Các dòng sau thực hiện một cách chính xác:

var airport: AnyObject! = Airport.MR_createEntity() 

(lldb) po airport <Airport: 0x7fcf54216940> (entity: Airport; id: 0x7fcf54216a20 <x-coredata:///Airport/t1D3D08DA-70F9-4DA0-9487-BD6047EE93692> ; data: { 
    open = nil; 
    shortName = nil; 
    visible = nil; }) 

trong khi dòng sau gây nên một EXC_BAD_ACCESS:

var airport2: Airport = Airport.MR_createEntity() as! Airport 

(lldb) po airport2 
error: Execution was interrupted, reason: EXC_BAD_ACCESS (code=1, address=0x0). 
The process has been returned to the state before expression evaluation. 

Không có dấu hiệu của lỗi này với mục tiêu chủ yếu của tôi. Cấu hình là: đối tượng mô hình trong cả hai mục tiêu, lớp được đặt trước bởi @objc(MyModel), không có không gian tên trong mô hình của lớp học trong

Bất kỳ ý tưởng gì đang xảy ra ở đây?

+0

Bạn đã đánh dấu phương pháp và thuộc tính của mình là công khai trong lớp Sân bay?Kiểm soát truy cập Swift có thể là vấn đề – railwayparade

+0

Chỉ cần thử, kết quả tương tự: ( – Yaman

+0

Tôi đã kết thúc việc tạo các đối tượng theo cách thủ công mà không cần viết tắt MR để chèn ... –

Trả lời

3

Phải, vì vậy cuối cùng tôi đã nhận được thông tin này và không đẹp. Có thực sự là một radar cho vấn đề này vì nó dường như là một lỗi với trình biên dịch Swift không nhận ra ManagedObject đúc trong các mục tiêu thử nghiệm. Vì vậy, thêm giọng nói của bạn để tiếng ồn

Khởi đầu với một thực thể được định nghĩa như sau:

@objc(Member) 
class Member: NSManagedObject {  
    @NSManaged var name: String 
} 

Tôi đã viết một lớp thử nghiệm đơn giản mà tôi tạo ra một MO trong 3 cách khác nhau:

Đầu tiên hai thất bại:

let context = NSManagedObjectContext.MR_defaultContext() 

func testMagicalRecordCreation() { 
    let m = Member.MR_createInContext(context) as? Member 
    XCTAssertNotNil(m, "Failed to create object")//fails 
} 

func testEntityDescriptionClassCreation() { 
    let m2 = NSEntityDescription.insertNewObjectForEntityForName("Member", inManagedObjectContext: context) as? Member 
    XCTAssertNotNil(m2, "Failed to create object")//fails 
} 

Và sau đó là một thành công

func testManualMOCreation() { 
    let ent = NSEntityDescription.entityForName("Member", inManagedObjectContext: context)! 
    let m3 = Member(entity: ent, insertIntoManagedObjectContext: context) 
    XCTAssertNotNil(m3, "Failed to create object") 
} 

Điều này có nghĩa là ngay bây giờ bạn có hai tùy chọn. Viết các bài kiểm tra của bạn trong Objective-C; hoặc tạo một phương thức tiện ích để chèn các đối tượng thử nghiệm vào một ngữ cảnh bằng cách sử dụng các phương tiện tôi đã trình bày ở trên.

Theres một bài tốt đẹp về hành vi này here

tôi đã kết thúc bằng một phần mở rộng NSManagedObjectContext sẽ được sử dụng một cách rõ ràng trong thử nghiệm Swift:

extension NSManagedObjectContext { 
    func insertTestEntity<T: NSManagedObject>(entity: T.Type) -> T { 
     let entityDescription = NSEntityDescription.entityForName(NSStringFromClass(T.self), inManagedObjectContext: self)! 
     return T(entity: entityDescription, insertIntoManagedObjectContext: self) 
    } 
} 

Và nó có thể được sử dụng như thế này:

func testConvenienceCreation() { 
    let m4 = context.insertTestEntity(Member) 
    XCTAssertNotNil(m4, "Failed to create object") 
} 

Đọc thêm về cách tiếp cận này here

0

Có hai cách để làm cho lớp ứng dụng Swift của bạn sẵn sàng cho mục tiêu kiểm tra:

  1. Make lớp ứng dụng của bạn nào - điều này bao gồm tất cả các biến, hằng số, và chức năng bạn muốn kiểm tra

  2. Thêm tệp Swift ứng dụng của bạn vào mục tiêu Thử nghiệm của bạn. Điều này khá đơn giản để làm.

+0

đây không phải là những gì OP đang yêu cầu ... –

Các vấn đề liên quan