Closed jzau closed 8 years ago
Are you using Hosted Tests (which launch the application target itself before starting the Unit Tests)? If so, be sure that you don't do any AFHTTPSessionManager
can in your application:didFinishLaunchingWithOptions:
method, because this would be executed before your Unit Tests and more importantly before OHHTTPStubs
get loaded in memory by Xcode, and thus the NSURLSession
created by AFHTTPSessionManager
would be created before OHHTTPStubs
could even install the stubbing protocol in it.
See also https://github.com/AliSoftware/OHHTTPStubs/issues/126#issuecomment-145149158 which might be similar to your problem, with detailed explanation on what might be happening in your project and how to solve it.
Thanks for your help.
Actually, I didn't use any AFHTTPSessionManager
in main project. I just create a new project without unit test but using Objc, than add unit test target using swift. Do nothing about main project. The test case with above codes still can't stub request.
Very strange. Did you compare your project with the example projects provided in the OHHTTPStubs repo to see what you did different?
In your sample project without AFHTTPSessionManager
, what did you use instead? If you used NSURLSession
and one of its task…
method, didn't you forget to call resume
on the task be sure to start the request, i.e. does the request even actually fire to the network if you don't try to stub it?
I even wonder if your initial issue ("it works in main project but not in tests") and the one in your simplified example ("can't stub when I try without AFHTTPSessionManager
") might be different problems (e.g. one where your test project might be misconfigured and the other where you didn't even start the request, as I too often forget to call resume
)
Did you try to place some breakpoints in the OHHTTPStubs
library code itself to see if it was even called, especially if it intercepted any request at all to test it against the isPath("/test")
and thus if what is wrong is the global setup of OHHTTPStubs
or if it's just the test isPath("/test")
that is checked but returns false, or whatnot?
I can't really see what's wrong without seeing your sample project anyway, because such code works in my example projects here. Maybe if you provide your sample project I could look at it and check.
I find that it can't stub request even when using NSURLSession
in test target. But it works with NSURLConnect
.
I tried to use breakpoints in OHHTTPStubs
library code in OHHTTPStubsSwift.swift
file.
I separate isExtension
for multiple lines so that it's easy to add breakpoint like this
public func isExtension(ext: String) -> OHHTTPStubsTestBlock {
return {
req in
req.URL?.pathExtension == ext
}
}
but it only stops in return
line.
Here is an example project. https://github.com/jackyzh/stubExample.
And I find that it works with NSURLSession.sharedSession
.
I haven't looked at your sample project yet, but, if it works with NSURLConnection
and NSURLSession.sharedSession
(which use NSURLProtocol
installed globally) but doesn't work with any other NSURLSession
(which are created from NSURLSessionConfiguration
objects), that means that you created your NSURLSession
before OHHTTPStubs
had a chance to load into memory and inject itself in NSURLSessionConfiguration
to swizzle its custom NSURLProtocol
in there.
Which is exactly what issues like #126 are about.
Try to make sure that OHHTTPStubs
is loaded in memory before you even create your NSURLSession(configuration:…)
so it has a chance to inject itself and intercept future requests. As explained in the Apple doc, once an NSURLSession
is created, its internal NSURLSessionConfiguration
is frozen and can't be modified, and this also means that OHHTTPStubs
can't inject itself there (which it does when the framework is loaded in memory, so usually as soon as the test target is loaded) which it's too late for any NSURLSession
created before that (like ones created in applicationDidFinishLaunching
, as explained in #126).
I'll take a look at your sample project in a second to see if that is exactly the case you're encountering or not and get back to you to confirm.
Ohhhh wait, just opened your sample project now… The problem is wayyyy simpler than all that! (Sorry for the misdirection in the previous comment)
You just forgot to include the subspec to add support for NSURLSession
in your Podfile
, so no wonder it doesn't work with NSURLSession
:wink:
In fact, the root spec pod 'OHHTTPStubs'
contains already the most-often used subspecs, including OHHTTPStubs/Core
, OHHTTPStubs/NSURLSession
, OHHTTPStubs/JSON
and OHHTTPStubs/OHPathHelpers
. This means that if you put pod 'OHHTTPStubs'
in your Podfile
you will already have them all and will then only opt-in for pod 'OHHTTPStubs/Swift'
for Swift support.
But if you specifically ask for subspecs only and not for the root pod — as you did in your Podfile
as you listed pod 'OHHTTPStubs/Swift
and pod 'OHHTTPStubs/OHPathHelpers'
but not pod 'OHHTTPStubs'
— then it only pick the specific subspecs you specify. So in that case you'll have to opt-in for the OHHTTPStubs/NSURLSession
subspec explicitly too.
The solution is:
pod 'OHHTTPStubs'
(which will include the OHPathHelpers
but also the NSURLSession
support) and pod 'OHHTTPStubs/Swift'
(to add Swift support — which is not included by default)pod 'OHHTTPStubs/NSURLSession'
to your Podfile
next to the existing two subspecs already declared there (you then won't have the JSON support and its ability to create JSON stubs from dictionaries easily, except if you opt-in to it too, but maybe you don't need it in your project and tests anyway, depends on your use cases)Tested locally by adding pod 'OHHTTPStubs/NSURLSession'
in your Podfile
, running pod install
then running the tests again, I can definitively confirm this was the reason for the issue.
Closing the issue now (but feel free to add comments here if you have remarks or don't manage to make it work in your end)
I have tried several times of different ways running the same pieces of codes. It works in main project but can't stub any request when it runs in test case.
Main project is written in Objective-C.