Might I be so inclined to ask for a hand and or different perspectives on how to Unit Test a function on my Viewcontroller that calls an HTTP request to a Back End server using promise kit which returns JSON that is then decoded into the data types needed and then mapped.
This is one of the promise kit functions (called in viewWillAppear) to get stock values etc...
func getVantage(stockId: String) {
firstly {
self.view.showLoading()
}.then { _ in
APIService.Chart.getVantage(stockId: stockId)
}.compactMap {
return $0.dataModel()
}.done { [weak self] data in
guard let self = self else { return }
self.stockValue = Float(data.price ?? "") ?? 0.00
self.valueIncrease = Float(data.delta ?? "") ?? 0.00
self.percentageIncrease = Float(data.deltaPercentage ?? "") ?? 0.00
let roundedPercentageIncrease = String(format: "%.2f", self.percentageIncrease)
self.stockValueLabel.text = "\(self.stockValue)"
self.stockValueIncreaseLabel.text = "+\(self.valueIncrease)"
self.valueIncreasePercentLabel.text = "(+\(roundedPercentageIncrease)%)"
}.ensure {
self.view.hideLoading()
}.catch { [weak self] error in
guard let self = self else { return }
self.handleError(error: error)
}
}
I've thought of using expectations to wait until the promise kit function is called in the unit test like so :
func testChartsMain_When_ShouldReturnTrue() {
//Arange
let sut = ChartsMainViewController()
let exp = expectation(description: "")
let testValue = sut.stockValue
//Act
-> Note : this code down here doesn't work
-> normally a completion block then kicks in and asserts a value then checks if it fulfills the expectation, i'm not mistaken xD
-> But this doesn't work using promisekit
//Assert
sut.getVantage(stockId: "kj3i19") {
XCTAssert((testValue as Any) is Float && !(testValue == 0.0))
exp.fulfill()
}
self.wait(for: [exp], timeout: 5)
}
but the problem is promisekit is done in its own custom chain blocks with .done being the block that returns a value from the request, thus i can't form the completion block on the unit test like in conventional Http requests like :
sut.executeAsynchronousOperation(completion: { (error, data) in
XCTAssertTrue(error == nil)
XCTAssertTrue(data != nil)
testExpectation.fulfill()
})