如果iOS应用程序有自己的请求,OHHTTPStubs不会嘲笑请求吗?
如果应用程序在测试运行之前执行任何Alamofire请求,OHHTTPStubs将不会在单元测试中模拟任何请求
OHHTTPStubs 4.3.0 with swift support
Alamofire 2.0.2
测试文件 - 按预期工作
stub(isHost("httpbin.org")) { _ in
let stubData = "Hello World!".dataUsingEncoding(NSUTF8StringEncoding)
return OHHTTPStubsResponse(data: stubData!, statusCode:200, headers:nil)
}
print("@@Start")
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.responseString() { request, response, data in
print(data)
}
但是,一旦将以下内容添加到AppDelegate.swift,它就不再有效,而是向服务发出实际的HTTP请求
Alamofire.request(.GET, "http://httpbin.org/get")
.responseString() { request, response, data in
print(data)
}
留给后人的原始问题
更新:我在一个干净的项目中再次尝试,它按预期工作,所以必须有其他事情发生。
在swift 2.0的最新升级中,OHHTTPStubs并未对请求进行存根,而是将它们传递给现场直播。
我在单元测试中设置了一个简短的例子,但它仍在通过。我错过了什么?
import Foundation
import Quick
import Nimble
import Alamofire
import OHHTTPStubs
class RequestsSpec: QuickSpec {
var data:Result<String>? = nil
override func spec() {
describe("the request") {
it("needs to make a request") {
stub(isHost("httpbin.org")) { _ in
let stubData = "Hello World!".dataUsingEncoding(NSUTF8StringEncoding)
return OHHTTPStubsResponse(data: stubData!, statusCode:200, headers:nil)
}
Alamofire.request(.GET, "http://httpbin.org/get", parameters: ["foo": "bar"])
.responseString() { request, response, data in
print(request)
print(response)
print(data)
print(data.value)
self.data = data
}
expect(self.data).toEventuallyNot(beNil(), timeout: 3)
}
}
}
我得到了
Optional(<NSMutableURLRequest: 0x7f91598e22e0> { URL: http://httpbin.org/get?foo=bar })
Optional(<NSHTTPURLResponse: 0x7f915da8c220> { URL: http://httpbin.org/get?foo=bar } { status code: 200, headers {
"Access-Control-Allow-Credentials" = true;
"Access-Control-Allow-Origin" = "*";
Connection = "keep-alive";
"Content-Length" = 364;
"Content-Type" = "application/json";
Date = "Thu, 01 Oct 2015 04:19:42 GMT";
Server = nginx;
} })
Optional("{\n \"args\": {\n \"foo\": \"bar\"\n }, \n \"headers\": {\n \"Accept\": \"*/*\", \n \"Accept-Encoding\": \"gzip;q=1.0,compress;q=0.5\", \n \"Accept-Language\": \"en-US;q=1.0\", \n \"Host\": \"httpbin.org\", \n \"User-Agent\": \"ios-consumer-app/com.dante.ouli2 (28; OS Version 9.0 (Build 13A340))\"\n }, \n \"url\": \"http://httpbin.org/get?foo=bar\"\n}\n")
而不是Hello World!
我尝试使用NSURLSession发出请求,OHHTTPStubs正常工作。看起来OHHTTPStubs / Alamofire互动有问题吗?
let url = NSURL(string: "http://httpbin.org/get")
let task = NSURLSession.sharedSession().dataTaskWithURL(url!) {(data, response, error) in
print(NSString(data: data!, encoding: NSUTF8StringEncoding))
self.data2 = data
}
答案 0 :(得分:1)
使用OHHTTPStubs打开一张票。这是Alamofire和OHHTTPStubs之间的优势案例
https://github.com/AliSoftware/OHHTTPStubs/issues/126 决议是在最后两个帖子的底部
修复边缘案例的一些想法:
- 切换到非托管测试,以便在加载测试包之前不启动应用程序
- 保持托管测试,但是将OHHTTPStubs添加到您的应用程序包而不是测试包中,以便在运行测试时启动应用程序时立即加载
- 以某种方式破解你的AppDelegate代码,这样当从测试中启动时,它不会对Alamofire.request进行任何调用,并且是Alamofire在应用程序或测试中发出的第一个请求(从而触发其调用只有在加载测试包并将其注入您的应用程序包后,才会创建创建其内部NSURLSessionConfiguration的Manager.sharedInstance。
我最终做了什么
我已经做到了,所以Alamofire请求不会在启动时生成
答案 1 :(得分:0)
运行应用程序/ UI测试时,Xcode在Simulator中启动应用程序,将Test bundle作为插件加载,然后在应用程序内执行单元测试。
实际的App和Test bundle都加载到内存中。如果您将OHHTTPStubs与App目标和Test目标相关联,则该库将被加载两次,并且将在内存中加载两个实例。这会导致Test包中的存根无法拦截App内的请求。
如果可能,请避免将OHHTTPStub链接到测试目标(您的应用程序),以便它只加载一次。
如果您确实需要在测试目标中包含OHHTTPStub,则可以在测试设置期间附加一个String作为launchEnvironment的标志。然后通过NSProcessInfo.processInfo()。环境[“SOME_STRING_FLAG”]检查您的应用程序内是否存在该标志。
有关此问题的更多信息,请阅读AliSoftware关于此问题的维基:https://github.com/AliSoftware/OHHTTPStubs/wiki/A-tricky-case-with-Application-Tests