XCTest Unit Test data response not set in test after viewDidLoad

I'm trying to write Unit Tests, and I'm currently trying to check the viewController that got the data in viewDidLoad(), the data is set after an alamofire request. The problem is that in my test function, when I check the array, which should be filled with 10 elements after a successful request, it is 0. I checked if it was running viewDidLoad()in the test, but it should be because when I just add elements to another array that is outside the request, a specific test is running. I assume this has something to do with the request, and I have not yet found an answer.

Here is the code (this explanation question helped me to execute viewDidLoad () viewController):

ViewController simplified :

class ViewController: UIViewController {

  var itemsFromRequest: [Int] = []
  var itemsWithoutRequest: [Int] = []

  override func viewDidLoad() {
    super.viewDidLoad()

    // array with 10 elements
    itemsWithoutRequest = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]

    Alamofire.request(url: URLConvertible).responseJSON { response in
      //...error handling, parsing etc.

      // set array after successful response
      self.itemsFromRequest = responseData
    }
  }
}

ViewControllerTests Class:

class ViewControllerTests: XCTestCase {

  var viewController: ViewController!

  override func setUp() {
    super.setUp()

    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    viewController = storyboard.instantiateViewController(withIdentifier: "ViewController") as! ViewController
    // trigger viewDidLoad() of viewController
    let _ = viewController.view
  }

  func testItemArraysHaveTenItems() {
    // This is successful
    XCTAssertEqual(viewController.itemsWithoutRequest.count, 10)
    // This failed with error "XCTAssertEqual failed: ("0") is not equal to ("10")"
    XCTAssertEqual(viewController.itemsFromRequest.count, 10)
  }
}

Why is the second statement not satisfied?

+2
source share
1 answer

Problem

In the second statement, you expect the data to load asynchronously, but you check it synchronously and while you check it, the network operation is not completed yet, so of course it will fail.

Decision

Testing is available asynchronously on iOS using XCTestExpectation .

Usage example

let testExpectation = expectation(description: "Asynchronous expectation")
let sut = SubjectUnderTest()

sut.executeAsynchronousOperation(completion: { (error, data) in
    XCTAssertTrue(error == nil)
    XCTAssertTrue(data != nil)

    testExpectation.fulfill()
})

waitForExpectations(timeout: 5, handler: .none)

Advice

: - , , . ( GitHub , Swift: OHHTTPStubs)

+4

Source: https://habr.com/ru/post/1678459/


All Articles