Skip to content

A small but nifty Swift unit test framework for stubbing network calls.

License

Notifications You must be signed in to change notification settings

atetlaw/shawshank

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

43 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Shawshank

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

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.

Installation

Carthage

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.)

Cocoapods

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

target 'MyAppTests' do
    pod 'Shawshank'
end

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

API Examples

Swift

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

Unit Test Example

func testShawshankMatchingDataTaskRespondingWithJSONDataFixture() {
    let testRequest = URLRequest(url: URL(string: "http://www.example.com")!)
    
    Shawshank.take(matching: .scheme("http") && .host("www.example.com")).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 }
        XCTAssertNil(error)
        XCTAssertEqual(httpResponse.statusCode, 200)
        XCTAssertNotNil(data)
        
        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")
        expect.fulfill()
    }.resume()
        
    waitForExpectations(timeout: 1, handler: nil)
}

Ackowledgments

Inspiration

About

A small but nifty Swift unit test framework for stubbing network calls.

Resources

License

Stars

Watchers

Forks

Packages

No packages published