-
Notifications
You must be signed in to change notification settings - Fork 602
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
OHHTTPStubs not mocking when Alamofire request made in AppDelegate #126
Comments
Did you read my dedicated troubleshooting page in my wiki? Especially this one explaining the difference between Hosted Tests (the app bundle is launched and the test bundle is injected into it ==> in that case you need to install the stubs in the app bundle) vs Standalone Tests (the test bundle is launched standalone, without the app bundle even needed to be build, and you install your stub in the tests bundle). If you want the stubs to be able to intercept any network request, you need to install them in the same bundle that is launched during test, which is the app bundle for hosted test or the test bundle for non-hosted tests. |
Thanks for the response! I didn't think it was a test set-up error because the tests were working before we updated to Swift 2.0 but perhaps it was just coincidental with some other changes we were making |
Yeah, hosted tests are now the default in Xcode, so maybe migrating to Xcode 7 force-changed that setup? |
Perhaps. I do have a question after reading the wiki. It says not to use OHHTTPStubs in the app code (to mock TBD services) - but in the sample code it's only in the test target. So if I understand correctly I do not need to "...avoid linking OHHTTPStubs to the test target so that it is only loaded once" since it's only loaded to the test target when the application loads? |
I'm not sure to follow.
On the contrary, you could use OHHTTPStubs in your app code when you need to mock TBD services
What is? iirc, the sample code displays some UISwitches in the main view to toggle the stubs, and those stubs are installed in the application code, not in the tests. Actually the example projects don't contain any test at all, as the Unit Testing of the library is done in the dedicated project building the library/framework in |
Sorry, I mean the wiki states don't use OHHTTPStubs in app and in unit tests when using hosted tests By sample code I'm referring to my sample of the "bug" I'm experiencing https://github.com/iwllyu/test-ohhttpstubs |
I just opened your sample project and that confirms what I stated earlier. You're using hosted tests apparently, so this means that Xcode will launch your app bundle (and call |
Thanks for taking a look. Okay here is where I am confused per the wiki
OHHTTPStubs is not linked in the app bundle, only the test bundle
It is fine (for now, anyways) if the Alamofire request in the App calls makes an actual request
This is not happening, the test Alamofire request is calling the actual service even though there is an OHHTTPStub registered before the request. Removing the Alamofire request in the app resolves this. Let me know if I misunderstood something |
So, I finally dug a bit deeper in your sample code, and this was indeed a tricky case, which I believe is linked with 3 factors:
All that explains why, when you're doing a request in your App code, the stubs are not properly setup in time. Here is what happens in practice:
Some ideas to fix your edge case:
The fact that the App bundle is loaded and your app is started (and the AppDelegate methods executed) before the test bundle (and |
I really appreciate the time you spent looking into this. I've made it so Alamofire requests aren't made during startup (there was a view controller being initialized that made the API call, I delayed the request until the viewWillAppear) - although we could also switch to non-hosted since we aren't doing any UI testing. Thanks again for all the help |
@AliSoftware: Your last comment here was very helpful for me as well. Thanks! |
@rcdilorenzo thanks for the feedback, glad it helped. It could maybe be a nice addition to make a wiki page or article about that; I'd be glad to add a link to it in the README if it can help others. |
God bless you @AliSoftware |
hello @AliSoftware I'm swift/xcode beginner and have to write some tests for my company's app. I'm sorry if it's a too silly question (and it's not related to
|
@igorbelo If you integrated If you integrated using Carthage, just change the OHHTTPStubs.framework target membership in the right panel one you have selected the framework in Xcode, to uncheck the "YourAppTests" checkbox and check "YourApp" checkbox instead. |
@AliSoftware even doing that I'm getting a hit in my API server...don't know if it's due an outdated version of CocoaPods (0.39.0) we are using. Digging a little bit more to see if worth to open an issue for that. UPDATE: even upgrading CocoaPods to last version and scoping the libs into targets I couldn't manage it to work. Podfile source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '8.0'
use_frameworks!
def shared_pods
# Forced using Github as source. Specifying only the Pod Name was fetching an older version
pod 'Pluralize.swift', git: 'https://github.com/joshualat/Pluralize.swift.git'
# Replacement for UIPageControl
pod 'SMPageControl'
# SwiftyJson
pod 'SwiftyJSON', :git => 'https://github.com/SwiftyJSON/SwiftyJSON.git'
# Alamofire https://github.com/Alamofire/Alamofire
pod 'Alamofire', '3.2.0'
# SwiftValidator https://github.com/jpotts18/SwiftValidator
pod 'SwiftValidator', '~> 3.0.1'
# https://github.com/honghaoz/AutoKeyboardScrollView
pod "AutoKeyboardScrollView", '~> 1.4'
# HanekeSwift https://github.com/Haneke/HanekeSwift
pod 'HanekeSwift'
# https://github.com/gilesvangruisen/Swift-YouTube-Player
pod 'YouTubePlayer'
# https://github.com/scalessec/Toast-Swift
pod 'Toast-Swift', '~> 1.3.0'
# https://github.com/oarrabi/OAStackView
pod 'OAStackView'
pod 'OHHTTPStubs/Swift'
end
target 'MyProject' do
shared_pods
pod 'OHHTTPStubs'
end
target 'MyProjectTests' do
shared_pods
end Test case import XCTest
@testable import MyProject
import OHHTTPStubs
class ApiClientTests: XCTestCase {
override func setUp() {
super.setUp()
stub(isPath("/api/notifications/")) { _ in
let stubData = "Hello World!".dataUsingEncoding(NSUTF8StringEncoding)
return OHHTTPStubsResponse(data: stubData!, statusCode:200, headers:nil)
}
}
override func tearDown() {
super.tearDown()
}
func testNotificationsWhenLoggedIn() {
let api = ApiClient.sharedInstance()
let expectation = expectationWithDescription("Alamofire")
api.notifications() { response in
XCTAssertTrue(response.success)
expectation.fulfill()
}
waitForExpectationsWithTimeout(5.0, handler: nil)
}
I'm using Alamofire and my Any ideas? |
We had to add -ObjC to the other linker flags in the app which makes the call. Then the stubs started working for us. We don't integrate via cocoa pods tho.
|
Well looking at your code it seems that you properly integrated OHHTTPStubs to your app bundle and not your test bundle like it seems you wanted to do (which would make sense only if you use Hosted Tests, which you probably do as it's the default in Xcode now and otherwise you wouldn't be able to link to OHHTTPStubs in your test target anyway). So now you'll have to ensure that Alamofire doesn't load itself and create its inner |
Ok, I've come across same issue yesterday, spent 4 hours debugging and... The problem was I've not included
Probably it's an issue for @igorbelo because his podfile omits |
maybe relevant to some - (the podspec doesn't actually work - doesn't look a pull request has been opened to cocoapods) https://github.com/michaelhayman/OHHTTPStubsExtensions |
@glyuck same problem as you, i spend the whole day. I suggest adding auto dependency if pod 'OHHTTPStubs/Swift' just include pod 'OHHTTPStubs'. |
@ivanruizscm I already explained the rationale in other issues and PRs as to why This is very well documented both in multiple places in the |
Hi @AliSoftware |
As explained the way the test harness used by Xcode for hosted tests (and thus UI tests) works is that Xcode launches the app itself then run the UI test code from the context of the app. So if you want to apply stubs in your app requests while UI testing your app, then sadly given how Xcode execute those tests there's no real magical solution other than writing your stubbing code in your app target. The general trick to do that is to test in your code if an env var is set and only setup the stubs in that case. Then configure your Xcode scheme so that the test action defines that env var while the run action doesn't. Variants of that approach exists by basing the test wether to setup stubs or not on the command line arguments (instead of an env var), optionally leveraging the ArgumentDomain of UserDefaults (setting up your scheme to pass arguments like |
Did you say you need to remove "A workaround if you really need it" section from your article? |
Not sure if I should post this issue here or over at Alamofire
I have a unit test that stubs httpbin.org, and then it makes an Alamofire request. The request is stubbed as expected.
If I then add an Alamofire request to AppDelegate, the stub in the unit test stops mocking and instead the Alamofire request in the unit test calls the actual service.
I have a sample here https://github.com/iwllyu/test-ohhttpstubs
The text was updated successfully, but these errors were encountered: