Unit Test – How to unwrap optional value in XCTest

by DaoNM2
149 views

Trước khi Xcode 11 ra mắt, để unwrap một optional value chúng ta vẫn thường phải dùng Guard/if let, điều này khá bất tiện trong khi viết Unit test. Khi viết test case chúng ta không nên đưa các câu lệnh điều kiện vào trong các func test vì nó sẽ tạo ra một logic mới trong Unit Test nó khiến test case của chúng ta rắc rối và phức tạp.

Để các bạn dễ hình dung hơn, mình có tạo một Struct Person có thuộc tính address là optional (có thể nil) như dưới đây:

struct Person {
    let name: String
    let address: String?
}

Thông thường chúng ta sẽ thực hiện unwrap như sau:

func test_Address_caseNil() throws {
    let personModel: Person = Person(name: "John", address: nil)
    // unwrap optional value 
    guard let address = personModel.address else {
        XCTFail("Expected non-nil address")// throw fail
        return
    }
    
    XCTAssertEqual(address, "Hanoi")
}

Trong trường hợp này địa chỉ đang nil nên test case này sẽ bị lỗi và throw thông báo “Expected non-nil address”

Có một cách thông dụng hơn là không unwrap mà sử dụng trực tiếp giá trị optional để verify test case như sau:

func test_address_caseNil() throws {
    let personModel: Person = Person(name: "John", address: nil)
    
    XCTAssertEqual(personModel.address, "Hanoi")
}

Khi chạy test case này ta nhận được thông báo lỗi như sau:

test_address_caseNil(): XCTAssertEqual failed: ("nil") is not equal to ("Optional("Hanoi")")

Sử dụng cách này thì khá là tiện và nhanh, tuy nhiên nó có một nhược điểm là các thông báo lỗi thường không rõ ràng. Ngoài ra nó cũng sẽ không sử dụng được trong các trường hợp đặc biệt.

Sử dụng XCTUnwrap

XCTUnwrap() được giới thiệu trên Xcode 11, nó làm nhiệm vụ kiểm tra giá trị optional có nil hay không? nếu nil nó sẽ throw ra lỗi, không nil thì trả về giá trị. Từ đó ta có thể thoải mái sử dụng giá trị đó để thực hiện việc testing.

func test_address_caseNil() throws {
    let personModel: Person = Person(name: "John", address: nil)
    // result
    let result = try XCTUnwrap(personModel.address)
    XCTAssertEqual(personModel.address, "Hanoi")
}

Sử dụng XCTUnwrap giúp source code của chúng ta gọn gàng sạch sẽ hơn rất nhiều so với các cách thông thường khác.

Để sử dụng được XCTUnwrap bạn nhớ thêm throws cho func test để khi kiểm tra dữ liệu bị nil nó sẽ throw lỗi và đánh dấu test case này bị fail. Nếu bạn muốn thông báo rõ ràng hơn hay đơn giản là bạn muốn viết thông báo lỗi dễ hiểu bạn có thể thêm thuộc tính như sau

 let result = try XCTUnwrap(personModel.address, "Width is nil, please config data for test case")

Thông báo lỗi ta nhận được sẽ như sau:

test_address_caseNil(): XCTUnwrap failed: expected non-nil value of type "String" - Width is nil, please config data for test case

Lúc này thông báo lỗi đã rõ ràng hơn, từ đó bạn có thể xử lí vấn đề một cách nhanh hơn.

Hi vọng bài viết sẽ giúp cho các bạn có thêm lựa chọn để xử lí các tình huống khi viết Unit Test, từ đó sử dụng nó một cách hiệu quả và phù hợp với các tình huống.

Leave a Comment

* By using this form you agree with the storage and handling of your data by this website.

You may also like