使用PromiseKit的单元测试功能

Hod*_*son 5 unit-testing ios swift 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")
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我创建的模拟管理器。

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
    }
}
Run Code Online (Sandbox Code Playgroud)

这是无效的测试。

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")
}
Run Code Online (Sandbox Code Playgroud)

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

Hod*_*son 3

事实证明我已经快到了,但我必须让我的模拟经理返回一个满足并通过一个ProductNSManagedObject子类)。现在我的模拟管理器看起来像这样,并且我的测试有效:

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
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `return Promise(value: Product)` 就足够了。 (3认同)