I have the following function which I want to test:
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")
}
}
}
}
}
Here is the mock manager I created.
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
}
}
And here is the non-working test.
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")
}
I know the mock manager is getting called but my expectation never gets fulfilled (exp.fulfill()
is not called) and I don't know why. Any ideas?
Turns out I was almost there but I had to make my mock manager return a fulfill and pass a Product
(NSManagedObject
subclass). So now my mock manager looks like this and my tests work:
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
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With