Unit Test

Introductions:

1. XCTestCase and Equality Assertion

  • XCTAssert(_)
  • XCTAssertEqual(_, _)
  • XCTAssertNotEqual(_, _)
  • XCTAssertLessThan(_, _)
  • XCTAssertLessThanOrEqual(_, _)
  • XCTAssertGreaterThan(_, _)
  • XCTAssertGreaterThanOrEqual(_, _)
  • XCTAssertNil(_)
  • XCTAssertNotNil(_)
  • XCTAssertTrue(_)
  • XCTAssertFalse(_)
  • XCTAssertNoThrow(_)
  • XCTAssertThrowsError(_)
  • XCTUnwrap(_)
  • XCTestExpectation(description: _)

2. Life Cycle

class LifeCycleExampleTest: XCTestCase {
    
    override class func setUp() {
        print("This runs before all tests")
    }
    
    override func setUpWithError() throws {
        print("This runs before each test")
    }
    
    override func tearDownWithError() throws {
        print("This runs after each test")
    }
    
    override class func tearDown() {
        print("This runs after all tests")
    }
    
    func testA() throws {
        print("This is test A")
    }
    
    func testB() throws {
        print("This is test B")
    }
}

3. Simple Example

    func divideNumber(_ number: Int) -> String {
        switch (number % 3 == 0, number % 5 == 0){
        case (false, false): return "not_divide"
        case (true, false): return "divide_by_3"
        case (false, true): return "divide_by_5"
        case (true, true): return "divibe_by_both_3_5"
        }
    }
    
    func test(value: String, expected matches: String) {
        print(value == matches ? "\(value) ✅PASSED" : "\(value) FAILED❌")
    }
    
    func testDivideNumber(){
        test(value: divideNumber(3), expected: "divide_by_3")
        test(value: divideNumber(5), expected: "divide_by_5")
        test(value: divideNumber(15), expected: "divibe_by_both_3_5")
    }

4. Test For Asynchronous code

    func testGetData(){
        let expectation = XCTestExpectation(description: "expectation async completed")
        Repository.loadData { data, messege in
            if let data = data?.first {
                XCTAssertEqual(data.title, "delectus aut autem")
                expectation.fulfill()
            }
        }
        wait(for: [expectation], timeout: 3.0)
    }
struct DataModel: Codable {
    let userID: Int
    let id: Int
    let title: String
    let completed: Bool

    enum CodingKeys: String, CodingKey {
        case userID = "userId"
        case id, title, completed
    }
}
class Repository {
    
    static func loadData(completion: @escaping(_ data: [DataModel]?, _ message: String?) -> Void){
        guard let url = URL(string: "https://jsonplaceholder.typicode.com/todos") else {
            print("Invalid API End Point")
            return
        }
        let request = URLRequest(url: url)
        
        URLSession.shared.dataTask(with: request) { data, response, error in
            if let data = data {
                if let response = try? JSONDecoder().decode([DataModel].self, from: data) {
                    completion(response, "successfully get data")
                }else{
                    completion(nil, "successfully went wrong")
                }
            }else{
                completion(nil, "successfully went wrong")
            }
        }.resume()
    }
    
}