简体   繁体   中英

Write unit test for function calling Async request and return nothing

Here is my ViewModel Call with function fetch Products, I need to test function which is internally calling Async request and setting some data

class ViewModel : NSObject {
    public var array : [Product]?
    func fetchProduct() {
        ProductRouter.fetchByCategory.send(modelType: ProductSearchResponse.self, success: { (success) in
        self.array = (success as! ProductSearchResponse).skus
    }, fail: { (error : NSError) in
        print(error.localizedDescription)
    }, showHUD: true)
   }
}


class MyNetworkRequestTests: XCTestCase {
    func testExample() {
    // This is an example of a functional test case.
    // Use XCTAssert and related functions to verify your tests produce the correct results.

       let url = Bundle(for: type(of: self)).url(forResource: "Listing", withExtension: "json")!
       let data = try! Data(contentsOf: url)
       stub(uri(ProductRouter.fetchByCategory.path), jsonData(data))
       let vm = ViewModel()
       vm.fetchProduct()
       XCTAssertNotNil(vm.sku)              
  }
}
// Json File have some Listing.json have correct json format.

So what you want to do is set up an expectation and wait for it

class MyNetworkRequestTests: XCTestCase {
    func testExample() {
    // This is an example of a functional test case.
    // Use XCTAssert and related functions to verify your tests produce the correct results.
       let expectation = expectation(description: "fetch expectation")
       let url = Bundle(for: type(of: self)).url(forResource: "Listing", withExtension: "json")!
       let data = try! Data(contentsOf: url)
       stub(uri(ProductRouter.fetchByCategory.path), jsonData(data))
       let vm = ViewModel()
       vm.fetchDone = {
            expectation.fullfill()
       }
       vm.fetchProduct()
       waitForExpectations(timeout: 10) { (error) in
             XCTAssertNotNil(vm.sku)
        }
  }
}

The "fetchDone" is this case will be whatever tells your viewController that the data has arrived. Basically looking like this:

class vc: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        let viewModel = vm()
        viewModel.fetchDone = {
            self.populate(array: viewModel.array)
        }
    }

    func populate(array: [String]) {

    }
}

class vm: NSObject {
    var fetchDone: (() ->())?
    var array: [String] = [] {
        didSet {
            fetchDone?()
        }
    }

    func fetchProduct() {
        // Do something
        self.array = ["some data"]
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM