ios - 使用 PromiseKit 的单元测试功能

标签 ios swift unit-testing promisekit

我有以下要测试的功能:

func getProduct(ean: String) -> Promise<Product> {
    return Promise { fullfill, reject in
        let urlString = BSConstants.BarcodeScanner.productEndpoint.stringByAppendingString(ean)
        serviceClient.GET(urlString, failure: { (error) in
            reject(error!)
        }) { (response) in
            if let json = response {
                self.storeProduct(json).then ({ returnedProduct in
                    fullfill(returnedProduct)
                }).error { returnedError in
                    // HANDLE ERROR
                    print("HANDLE ERROR")
                }
            }
        }
    }
}

这是我创建的模拟经理。

class MockStoreProductProductManager: BSProductManagerSwift {
    var storeProductWasCalled = false
    var storeProductJSON: JSON?
    let deferredPromise = Promise<Product>.pendingPromise()

    override func storeProduct(json: JSON) -> Promise<Product> {
        storeProductWasCalled = true
        storeProductJSON = json

        return deferredPromise.promise
    }
}

这是非工作测试。

func testGetProduct_WithInStockEAN_RetunsValidInstockJSON() {
    // Given
    let mockManager = MockStoreProductProductManager(serviceClient: BSNetworkingServiceClient())
    let inputEanString = "1234567891234"

    var expectedJSON: JSON? = nil
    if let jsonPath = NSBundle(forClass: self.dynamicType).pathForResource("getproduct-instock-response", ofType: "json") {
        let data = NSData(contentsOfFile: jsonPath)!
        stub(http(.GET, uri: "some-url-i-have-removed"), builder: jsonData(data))

        let jsonResponse = JSON(data: data)
        expectedJSON = jsonResponse["data"]
    }

    // When

    let exp = expectationWithDescription("Return instock product JSON")

    mockManager.getProduct(inputEanString).then { returnedProduct in
        exp.fulfill()
    }.error { error in
        XCTFail("🔴 Instock JSON should have been returned")
        exp.fulfill()
    }

    waitForExpectationsWithTimeout(10, handler: nil)

    // Then
    XCTAssertTrue(mockManager.storeProductWasCalled, "🔴 Expected storeProduct function to be called but it wasn't")
    XCTAssertEqual(mockManager.storeProductJSON, expectedJSON, "🔴 Incorrect JSON passed to storeProduct")
}

我知道正在调用模拟管理器,但我的期望从未实现(未调用 exp.fulfill()),我不知道为什么。有什么想法吗?

最佳答案

事实证明我快到了,但我不得不让我的模拟管理器返回一个 fulfill 并传递一个 Product(NSManagedObject 子类)。所以现在我的模拟经理看起来像这样并且我的测试有效:

class MockStoreProductProductManager: BSProductManagerSwift {
    var storeProductWasCalled = false
    var storeProductJSON: JSON?
    let deferredPromise = Promise<Product>.pendingPromise()

    override func storeProduct(json: JSON) -> Promise<Product> {
        storeProductWasCalled = true
        storeProductJSON = json

        let managedObjectContext = setUpInMemoryManagedObjectContext()
        let entity = NSEntityDescription.entityForName("Product", inManagedObjectContext: managedObjectContext)
        let product = Product(entity: entity!, insertIntoManagedObjectContext: managedObjectContext)
        deferredPromise.fulfill(product)

        return deferredPromise.promise
    }
}

关于ios - 使用 PromiseKit 的单元测试功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38874869/

相关文章:

swift - SKCropNode 奇怪的行为

java - 如何编写单元测试以从 Java Set 中检索项目

javascript - 在 Javascript 中检测 Ipad Iphone 上的隐藏键盘按钮

ios - 在 ScrollView 中切换 VStack 的饱和度 - SwiftUI

ios - 如何在 iOS 上创建单色 UIImage

ios - 有没有一种实用的方法来压缩 NSData?

swift - 当应用程序进入后台时按钮跳转位置

ios - AVAudioPlayerNode 完成处理程序计时

unit-testing - 测试具有来自src/groovy的bean的grails Controller

unit-testing - 从 Spock 测试中动态排除类