MockWebServer是一个用于与XCTest框架一起工作的非常简单的Web服务器。MockWebServer模拟了Web服务器的行为。用户可以通过匹配请求模式来指定服务器的响应头和正文。其想法是它可以与Square为Android开发的MockWebServer类似,以便单元测试或UI测试可以根据服务器的响应执行测试用例。由于用户可以在测试用例中指定服务器的响应,因此用户可以确定测试用例应该如何表现。
MockWebServer与objective-c和swift兼容,并且它还可以与Cocoapods或Carthage一起使用。要在Carthage中使用MockWebServer,您只需简单地将此行添加到Carfile
中。
github "odinasoftware/MockWebServer"
MockWebServer仅使用objective-c实现,因此它可以与objective-c或任何版本的swift一起使用。
MockWebServer需要本地连接到服务器。因此,用户需要连接到localhost
及MockWebServer监听的端口号。例如,如果服务器从mockWebServer.start(9000)
启动,则用户可以根据下述示例连接到MockWebServer:
let url = NSURL(string: "http://127.0.0.1:9000/test")
...
let task = URLSession.shared.dataTask(with: url! as URL) {
(data, response, error) in
...
}
如果用户希望在单元测试中透明地运行应用程序,则需要配置应用程序环境,以便在运行测试用例时连接到localhost
。例如,在setUp
中,用户可能设置如下环境:
let app = XCUIApplication()
app.launchEnvironment["LOCAL_SERVER"] = "YES"
app.launch()
现在,当您应用程序启动时,您可以检查是否从UI测试用例启动,如下所示:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
// Override point for customization after application launch.
if ([[NSProcessInfo processInfo].environment objectForKey:@"LOCAL_SERVER"] != nil) {
// Your environment detects UI test, use local server instead.
}
return YES;
}
要运行示例项目,请克隆仓库,并从示例目录首先运行pod install
。
在setUp
中初始化MockWebServer
,并使用端口号运行start
。
- (void)setUp {
[super setUp];
mockWebServer = [[MockWebServer alloc] init];
[mockWebServer start:9000];
}
当测试用例完成时,您需要通过运行stopServer
来停止服务器。您可以在测试分解时运行stopServer
。
- (void)tearDown {
[super tearDown];
[mockWebServer stopServer];
}
一个dispatch将包含一个要模拟的请求模式以及要模拟的响应头和响应正文。
Dispatch *dispatch = [[Dispatch alloc] init];
[dispatch requestContainString:@"test"];
[dispatch setResponseCode:200];
[dispatch responseString:@"test"];
[dispatch responseHeaders:@{@"Accept-encoding": @"*.*"}];
此功能将匹配任何包含 "test" 的请求,并生成响应代码 200 和相应的响应头。响应体将包含 "test"。创建分发后,您需要将该分发添加到分发映射(dispatchMap)中,并将其设置为模拟服务器。
[dispatchMap addDispatch:dispatch];
[mockWebServer setDispatch:dispatchMap];
您可以使用 NSURLSessionDataTask
来运行一个普通的 URL 请求。
NSString *dataUrl = @"http://127.0.0.1:9000/test";
NSURL *url = [NSURL URLWithString:dataUrl];
NSURLSessionDataTask *test = [[NSURLSession sharedSession]
dataTaskWithURL:url completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
// 4: Handle response here
NSLog(@"data=%@", [NSString stringWithUTF8String:[data bytes]]);
XCTAssert([[NSString stringWithUTF8String:[data bytes]] compare:@"test"]==0, @"Body doesn't match.");
[testWait wakeup];
}];
由于任务异步执行,测试必须等待异步任务完成。您可能需要使用辅助函数来实现这一点。首先需要创建 TestConditionWait
,然后等待 URL 任务重新开始。
TestConditionWait *testWait = [TestConditionWait instance];
...
[test resume];
[testWait waitFor:1];
testWait
会等待直到 [testWait wakeup]
被调用。用户也可以指定等待的线程数量。
在 setup()
方法中,用户需要启动 MockWebServer 并指定服务器端口号。
override func setUp() {
super.setUp()
...
mockWebServer.start(9000)
}
单元测试完成后,用户需要停止服务器。
override func tearDown() {
super.tearDown()
...
mockWebServer.stop()
}
与 Objective-C 示例一样,用户需要指定用于响应的分发。
let dispatch: Dispatch = Dispatch()
dispatch.requestContain("test1")
.setResponseCode(200)
.responseString("test")
.responseHeaders(["Accept-encoding": "*.*"])
dispatchMap.add(dispatch)
用户也可以在测试用例中对多个分发进行模拟以模拟多个响应。
let dispatch1: Dispatch = Dispatch()
dispatch1.requestContain("test2")
.setResponseCode(200)
.responseBody(for: Bundle(for: object_getClass(self)), fromFile: "response.json")
.responseHeaders(["Accept-encoding": "*.*"])
dispatchMap.add(dispatch1)
用户创建了两个与两个响应相对应的分发,需要将这些分发添加到分发映射中。
mockWebServer.setDispatch(dispatchMap)
let task = URLSession.shared.dataTask(with: url! as URL) {
(data, response, error) in
debugPrint("response data=", data ?? "response null")
debugPrint("response headers=", response ?? "no response header")
testCondition.wakeup()
}
task.resume()
let task2 = URLSession.shared.dataTask(with: url2! as URL) {
(data, response, error) in
debugPrint("response data=", data ?? "response null", "\n")
debugPrint("response headers=", response ?? "no response header", "\n")
testCondition.wakeup()
}
task2.resume()
testCondition.wait(for: 2)
正如 Objective-C 示例所示,用户可以使用 TestConditionWait
来等待数据线程完成。在这种情况下,我们需要等待两个数据任务。
MockWebServer 通过 CocoaPods 提供。要安装它,只需将以下行添加到您的 Podfile 中
pod "MockWebServer"
Jae Han, [email protected]
MockWebServer 在 MIT 许可证下提供。有关更多信息,请参阅 LICENSE 文件。