MockWebServer 0.1.4

MockWebServer 0.1.4

测试已测试
Lang语言 Obj-CObjective C
许可 MIT
发布上次发布2016年12月

Odina Software维护。



  • 作者:
  • jaehan

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

Objective C 示例

初始化MockWebServer

setUp中初始化MockWebServer,并使用端口号运行start

- (void)setUp {
    [super setUp];
    mockWebServer = [[MockWebServer alloc] init];
    [mockWebServer start:9000];
}

当测试用例完成时,您需要通过运行stopServer来停止服务器。您可以在测试分解时运行stopServer

- (void)tearDown {
    [super tearDown];
    [mockWebServer stopServer];
}

创建Dispatch和DispatchMap

一个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];

使用 MockWebServer 运行测试

您可以使用 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] 被调用。用户也可以指定等待的线程数量。

Swift 示例

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 文件。