Latest 0.0.4
License MIT
Platforms ios 9.0

"I guess it comes down to a simple choice, really. Get busy testing or get busy crying."

As seen in Testing Tips & Tricks from WWDC2018 Using an URLProtocol subclass is a great way to mock responses from network calls in unit tests, but it can be laborious to setup. The goal of Shawshank was to make mocking a network response a one-liner.

It does 2 things: creates a way to match network requests, and specifies what sort of response to return if the match is true.



In your Cartfile use:

github "atetlaw/shawshank"

Shawshank only needs to be added to your unit testing target not your app’s main target. Remember to add the Carthage run script phase to your testing target, as well as adding Shawshank.framework to your Link Binaries With Libraries phase (Just click on the + button, the Add Other... button, and select the Shawshank.framework file in the Carthage/Build folder.)


Add pod 'Shawshank' to your Podfile, but limit it to your testing target like so:

target 'MyAppTests' do
    pod 'Shawshank'

Where MyAppTests is the name of your app’s unit test target. Then run a pod install.

API Examples


// Match any requests to `` and return the HTTP status: Not Permitted
Shawshank.take(matching: .scheme("http") && .host("")).httpStatus(.notPermitted)
let json = Bundle(for: ShankPublicAPITests.self).json(named: "test")
Shawshank.take(matching: .scheme("http") && .host("")).fixture(json)
Shawshank.take { (components: URLComponents) in
    return == "" && components.port == 82

Unit Test Example

func testShawshankMatchingDataTaskRespondingWithJSONDataFixture() {
    let testRequest = URLRequest(url: URL(string: "")!)

    Shawshank.take(matching: .scheme("http") && .host("")).fixture(JSONDataFixture(["test":"json"]))

    let expect = expectation(description: "response successful")
    URLSession.shared.dataTask(with: testRequest) { (data, response, error) -> Void in
        guard let httpResponse = response as? HTTPURLResponse else { return }
        XCTAssertEqual(httpResponse.statusCode, 200)

        guard let data = data else { XCTFail(); return }
        guard let json = try? JSONSerialization.jsonObject(with: data, options:[]) as? Dictionary<String, String> else { XCTFail(); return }

        XCTAssertEqual(json?["test"], "json")

    waitForExpectations(timeout: 1, handler: nil)



Latest podspec

    "name": "Shawshank",
    "version": "0.0.4",
    "license": "MIT",
    "summary": "Easy stubbing for network calls in Swift unit tests",
    "homepage": "",
    "authors": {
        "Andrew Tetlaw": "[email protected]"
    "source": {
        "git": "",
        "tag": "0.0.4"
    "source_files": "Shawshank/*.swift",
    "platforms": {
        "ios": "9.0"
    "swift_version": "4.2"

Pin It on Pinterest

Share This