Platformsosx 10.9, ios 8.0, requires ARC

Build Status

Are you a dependency injection devotee? Let’s mock URLSession together.


  • No need to modify production code to mock URLSession
  • Customizable URL matching logic to mock responses
  • Testable that the mocked responses are surely called


CocoaPods (iOS 8+, OS X 10.9+)

You can use Cocoapods to install MockURLSession by adding it to your Podfile:

platform :ios, '8.0'

target 'MyAppTest' do
    pod 'MockURLSession'

Note that this requires CocoaPods version 36, and your iOS deployment target to be at least 8.0.


Quick glance

Let’s look through an example to test MyApp below.

class MyApp {
    static let apiUrl = URL(string: "")!
    let session: URLSession
    var data: Data?
    var error: Error?
    init(session: URLSession = URLSession.shared) {
        self.session = session
    func doSomething() {
        session.dataTask(with: MyApp.apiUrl) { (data, _, error) in
   = data
            self.error = error

In the test code,

import MockURLSession

and write testing by any flamewrorks you prefer sush as XCTest (Written by print here).

// Initialization
let session = MockURLSession()
// Or, use shared instance as `URLSession` provides
// MockURLSession.sharedInstance

// Setup a mock response
let data = "Foo 123".data(using: .utf8)!
session.registerMockResponse(MyApp.apiUrl, data: data)

// Inject the session to the target app code and the response will be mocked like below
let app = MyApp(session: session)

print(String(!, encoding: .utf8)!)  // Foo 123
print(app.error as Any)    // nil

// Make sure that the data task is resumed in the app code
print(session.resumedResponse(MyApp.apiUrl) != nil)  // true

URL matching customization

// Customize URL matching logic if you prefer
class Normalizer: MockURLSessionNormalizer {
    func normalize(url: URL) -> URL {
        // Fuzzy matching example
        var components = URLComponents() =
        components.path = url.path
        return components.url!
// Note that you should setup the normalizer before registering mocked response
let data = NSKeyedArchiver.archivedData(withRootObject: ["username": "abc", "age": 20])
let session = MockURLSession()
session.normalizer = Normalizer()
session.registerMockResponse(MyApp.apiUrl, data: data)



Development tips


Get started

Run test on your environment:

bundle install --path vendor/bundle
bundle exec rake

A long way to bump up spec version

  1. Xcode: MockURLSession > Identity > Version
  2. Pod: s.version in MockURLSession.podspec
  3. Git: git tag 2.x.x && git push origin --tag
  4. Release by bundle exec pod trunk push MockURLSession.podspec

Latest podspec

    "name": "MockURLSession",
    "version": "2.0.0",
    "summary": "MockURLSession provides a way to mock NSURLSession.",
    "homepage": "",
    "license": {
        "type": "MIT"
    "authors": {
        "Kenta Yamamoto": ""
    "source": {
        "git": "",
        "tag": "2.0.0"
    "source_files": "MockURLSession/*.swift",
    "requires_arc": true,
    "platforms": {
        "osx": "10.9",
        "ios": "8.0"

Pin It on Pinterest

Share This