Mock Alamofire and URLSession requests without touching your code implementation

Related tags

Testing Mocker
Overview

Mocker is a library written in Swift which makes it possible to mock data requests using a custom URLProtocol.

Features

Run all your data request unit tests offline 🎉

  • Create mocked data requests based on an URL
  • Create mocked data requests based on a file extension
  • Works with URLSession using a custom protocol class
  • Supports popular frameworks like Alamofire

Usage

Unit tests are written for the Mocker which can help you to see how it works.

Activating the Mocker

The mocker will automatically be activated for the default URL loading system like URLSession.shared after you've registered your first Mock.

Custom URLSessions

To make it work with your custom URLSession, the MockingURLProtocol needs to be registered:

let configuration = URLSessionConfiguration.default
configuration.protocolClasses = [MockingURLProtocol.self]
let urlSession = URLSession(configuration: configuration)
Alamofire

Quite similar like registering on a custom URLSession.

let configuration = URLSessionConfiguration.af.default
configuration.protocolClasses = [MockingURLProtocol.self]
let sessionManager = Alamofire.Session(configuration: configuration)

Register Mocks

Create your mocked data

It's recommend to create a class with all your mocked data accessible. An example of this can be found in the unit tests of this project:

public final class MockedData {
    public static let botAvatarImageResponseHead: Data = try! Data(contentsOf: Bundle(for: MockedData.self).url(forResource: "Resources/Responses/bot-avatar-image-head", withExtension: "data")!)
    public static let botAvatarImageFileUrl: URL = Bundle(for: MockedData.self).url(forResource: "wetransfer_bot_avater", withExtension: "png")!
    public static let exampleJSON: URL = Bundle(for: MockedData.self).url(forResource: "Resources/JSON Files/example", withExtension: "json")!
}
JSON Requests
let originalURL = URL(string: "https://www.wetransfer.com/example.json")!
    
let mock = Mock(url: originalURL, dataType: .json, statusCode: 200, data: [
    .get : try! Data(contentsOf: MockedData.exampleJSON) // Data containing the JSON response
])
mock.register()

URLSession.shared.dataTask(with: originalURL) { (data, response, error) in
    guard let data = data, let jsonDictionary = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String: Any] else {
        return
    }
    
    // jsonDictionary contains your JSON sample file data
    // ..
    
}.resume()
Ignoring the query

Some URLs like authentication URLs contain timestamps or UUIDs in the query. To mock these you can ignore the Query for a certain URL:

/// Would transform to "https://www.example.com/api/authentication" for example.
let originalURL = URL(string: "https://www.example.com/api/authentication?oauth_timestamp=151817037")!
    
let mock = Mock(url: originalURL, ignoreQuery: true, dataType: .json, statusCode: 200, data: [
    .get : try! Data(contentsOf: MockedData.exampleJSON) // Data containing the JSON response
])
mock.register()

URLSession.shared.dataTask(with: originalURL) { (data, response, error) in
    guard let data = data, let jsonDictionary = (try? JSONSerialization.jsonObject(with: data, options: [])) as? [String: Any] else {
        return
    }
    
    // jsonDictionary contains your JSON sample file data
    // ..
    
}.resume()
File extensions
let imageURL = URL(string: "https://www.wetransfer.com/sample-image.png")!

Mock(fileExtensions: "png", dataType: .imagePNG, statusCode: 200, data: [
    .get: try! Data(contentsOf: MockedData.botAvatarImageFileUrl)
]).register()

URLSession.shared.dataTask(with: imageURL) { (data, response, error) in
    let botAvatarImage: UIImage = UIImage(data: data!)! // This is the image from your resources.
}.resume()
Custom HEAD and GET response
let exampleURL = URL(string: "https://www.wetransfer.com/api/endpoint")!

Mock(url: exampleURL, dataType: .json, statusCode: 200, data: [
    .head: try! Data(contentsOf: MockedData.headResponse),
    .get: try! Data(contentsOf: MockedData.exampleJSON)
]).register()

URLSession.shared.dataTask(with: exampleURL) { (data, response, error) in
	// data is your mocked data
}.resume()
Delayed responses

Sometimes you want to test if cancellation of requests is working. In that case, the mocked request should not finished directly and you need an delay. This can be added easily:

let exampleURL = URL(string: "https://www.wetransfer.com/api/endpoint")!

var mock = Mock(url: exampleURL, dataType: .json, statusCode: 200, data: [
    .head: try! Data(contentsOf: MockedData.headResponse),
    .get: try! Data(contentsOf: MockedData.exampleJSON)
])
mock.delay = DispatchTimeInterval.seconds(5)
mock.register()
Redirect responses

Sometimes you want to mock short URLs or other redirect URLs. This is possible by saving the response and mock the redirect location, which can be found inside the response:

Date: Tue, 10 Oct 2017 07:28:33 GMT
Location: https://wetransfer.com/redirect

By creating a mock for the short URL and the redirect URL, you can mock redirect and test this behaviour:

let urlWhichRedirects: URL = URL(string: "https://we.tl/redirect")!
Mock(url: urlWhichRedirects, dataType: .html, statusCode: 200, data: [.get: try! Data(contentsOf: MockedData.redirectGET)]).register()
Mock(url: URL(string: "https://wetransfer.com/redirect")!, dataType: .json, statusCode: 200, data: [.get: try! Data(contentsOf: MockedData.exampleJSON)]).register()
Ignoring URLs

As the Mocker catches all URLs by default when registered, you might end up with a fatalError thrown in cases you don't need a mocked request. In that case you can ignore the URL:

let ignoredURL = URL(string: "www.wetransfer.com")!
Mocker.ignore(ignoredURL)

However if you need the Mocker to catch only mocked URLs and ignore every other URL, you can set the mode attribute to .optin.

Mocker.mode = .optin

If you want to set the original mode back, you have just to set it to .optout.

Mocker.mode = .optout
Mock errors

You can request a Mock to return an error, allowing testing of error handling.

Mock(url: originalURL, dataType: .json, statusCode: 500, data: [.get: Data()],
     requestError: TestExampleError.example).register()

URLSession.shared.dataTask(with: originalURL) { (data, urlresponse, err) in
    XCTAssertNil(data)
    XCTAssertNil(urlresponse)
    XCTAssertNotNil(err)
    if let err = err {
        // there's not a particularly elegant way to verify an instance
        // of an error, but this is a convenient workaround for testing
        // purposes
        XCTAssertEqual("example", String(describing: err))
    }

    expectation.fulfill()
}.resume()
Mock callbacks

You can register on Mock callbacks to make testing easier.

var mock = Mock(url: request.url!, dataType: .json, statusCode: 200, data: [.post: Data()])
mock.onRequest = { request, postBodyArguments in
    XCTAssertEqual(request.url, mock.request.url)
    XCTAssertEqual(expectedParameters, postBodyArguments as? [String: String])
    onRequestExpectation.fulfill()
}
mock.completion = {
    endpointIsCalledExpectation.fulfill()
}
mock.register()
Mock expectations

Instead of setting the completion and onRequest you can also make use of expectations:

var mock = Mock(url: url, dataType: .json, statusCode: 200, data: [.get: Data()])
let requestExpectation = expectationForCompletingMock(&mock)
let completionExpectation = expectationForCompletingMock(&mock)
mock.register()

URLSession.shared.dataTask(with: URLRequest(url: url)).resume()

wait(for: [requestExpectation, completionExpectation], timeout: 2.0)

Communication

  • If you found a bug, open an issue.
  • If you have a feature request, open an issue.
  • If you want to contribute, submit a pull request.

Installation

CocoaPods

CocoaPods is a dependency manager for Cocoa projects. You can install it with the following command:

$ gem install cocoapods

To integrate Mocker into your Xcode project using CocoaPods, specify it in your Podfile:

source 'https://github.com/CocoaPods/Specs.git'
platform :ios, '10.0'
use_frameworks!

target '<Your Target Name>' do
    pod 'Mocker', '~> 2.2.0'
end

Then, run the following command:

$ pod install

Carthage

Carthage is a decentralized dependency manager that builds your dependencies and provides you with binary frameworks.

You can install Carthage with Homebrew using the following command:

$ brew update
$ brew install carthage

To integrate Mocker into your Xcode project using Carthage, specify it in your Cartfile:

github "WeTransfer/Mocker" ~> 2.3.0

Run carthage update to build the framework and drag the built Mocker.framework into your Xcode project.

Swift Package Manager

The Swift Package Manager is a tool for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies.

Manifest File

Add Mocker as a package to your Package.swift file and then specify it as a dependency of the Target in which you wish to use it.

import PackageDescription

let package = Package(
    name: "MyProject",
    platforms: [
       .macOS(.v10_15)
    ],
    dependencies: [
        .package(url: "https://github.com/WeTransfer/Mocker.git", .upToNextMajor(from: "2.3.0"))
    ],
    targets: [
        .target(
            name: "MyProject",
            dependencies: ["Mocker"]),
        .testTarget(
            name: "MyProjectTests",
            dependencies: ["MyProject"]),
    ]
)

Xcode

To add Mocker as a dependency to your Xcode project, select File > Swift Packages > Add Package Dependency and enter the repository URL.

Resolving Build Errors

If you get the following error: cannot find auto-link library XCTest and XCTestSwiftSupport, set the following property under Build Options from No to Yes.
ENABLE_TESTING_SEARCH_PATHS to YES

Manually

If you prefer not to use any of the aforementioned dependency managers, you can integrate Mocker into your project manually.

Embedded Framework

  • Open up Terminal, cd into your top-level project directory, and run the following command "if" your project is not initialized as a git repository:

    $ git init
  • Add Mocker as a git submodule by running the following command:

    $ git submodule add https://github.com/WeTransfer/Mocker.git
  • Open the new Mocker folder, and drag the Mocker.xcodeproj into the Project Navigator of your application's Xcode project.

    It should appear nested underneath your application's blue project icon. Whether it is above or below all the other Xcode groups does not matter.

  • Select the Mocker.xcodeproj in the Project Navigator and verify the deployment target matches that of your application target.

  • Next, select your application project in the Project Navigator (blue project icon) to navigate to the target configuration window and select the application target under the "Targets" heading in the sidebar.

  • In the tab bar at the top of that window, open the "General" panel.

  • Click on the + button under the "Embedded Binaries" section.

  • Select Mocker.framework.

  • And that's it!

    The Mocker.framework is automagically added as a target dependency, linked framework and embedded framework in a copy files build phase which is all you need to build on the simulator and a device.


Release Notes

See CHANGELOG.md for a list of changes.

License

Mocker is available under the MIT license. See the LICENSE file for more info.

Comments
  • Installation via CocoaPods is Broken

    Installation via CocoaPods is Broken

    Follow up on https://github.com/WeTransfer/Mocker/issues/88 and https://github.com/WeTransfer/Mocker/issues/89

    https://github.com/WeTransfer/Mocker/issues/89 actually resolved the build-time issue but it actually crashes the app during runtime.

    I tried importing XCTest.framework in my project (embed & sign, embed without signing, do not embed), but none of these options worked for me.

    help wanted 
    opened by rogerluan 28
  • Add Dynamic Mock support

    Add Dynamic Mock support

    Sometimes you want the same URL to return different results at different times during a test - for example, an error payload first and then a success payload.

    Dynamic Mock support enables this by allowing one to setup a closure (onMockFor) that gets called as a first step in mock matching (in Mocker's mock(for request: URLRequest) -> Mock?). If this closure returns a Mock, that is the mock returned from mock(for …) and is used to fulfill the mocked network request.


    The particular use case I had was for a service call made with an expired token. The networking layer in this app will catch the expired token error, automatically make a refresh token service call, and then auto-retry the original service call.

    In this situation I needed to have the mock for the original service call return a 401 for the expired token as long as the currentToken doesn't match the newGoodToken returned by the mocked refresh token call (which is auto-saved into currentToken by the networking layer).

    So my (simplified) onMockFor will look something like this:

    let refreshMock = Mock(url: refreshURL, dataType: .json, statusCode: 200, data: [.get: goodRefreshTokenData])
    refreshMock.register()
    let failureMock = Mock(url: serviceURL, dataType: .json, statusCode: 401, data: [.get, Data()])
    failureMock.register()
    
    let successMock = Mock(url: serviceURL, dataType: .json, statusCode: 200, data: [.get: goodMockData])
    // Note: do not register! Will overwrite failureMock (same URL).
    
    // Then add the `onMockFor` closure to check if we have the new token
    Mocker.onMockFor = { (request: URLRequest) -> Mock? in
      guard request.url == serviceURL else { return nil }
      if currentToken == newGoodToken {
          return successMock
      }
      return nil
    }
    

    Seemed like it might be useful to others, and I'd rather not maintain our own custom fork of Mocker separate from yours, so I thought I'd open a PR for this feature in case you'd like to incorporate it in Mocker proper. Tried to stick to your format and style and the majority of the code added is tests. Happy to change things to make it work better for you.

    opened by haikusw 16
  • feat: Global mode to choose only to mock registered routes

    feat: Global mode to choose only to mock registered routes

    Hello, This is my first time contribution ever. Yesterday I wrote a question / feature request for our needs: https://github.com/WeTransfer/Mocker/issues/83

    After checking out the source, I found an easy way to integrate this feature without changing the current way it works. So I propose a Pull request to integrate it.

    This feature adds a new property to the Mocker struct called mode. By default the current mode is .optout meaning you have to manually define all the routes you want the system to ignore and thus to process as if the mocker does not exist. This is the way it works today. The other mode is .optin used to let all the routes being processed as if there were no mocking system, except for the mocked routes.

    The use case leading to this feature is when you have an existing API with many routes, and a team has to develop a new route, for your development phase, you can mock only this route, to keep using you app and all the other routes in a complete transparent way.

    I hope you'll find this useful.

    opened by letatas 14
  • mocking

    mocking "failed" network interactions

    I didn't see any clear means of returning a failed network interaction (no route to host, for example) with Mocker, but I wanted that for some testing of my own.

    I've made a slight modification in a forked version that has an additional initializer ('reportFailure' - a boolean) that will return throw exception on URL access instead of returning Data & a response code. Is this something you'd like as a pull request?

    I wanted to offer, but wasn't sure how/if you wanted contributions to this library. I'm using it a bit differently than it was originally designed - more for testing failure scenarios, but it served me pretty well where I needed it: forked variant at https://github.com/heckj/swiftui-notes/blob/master/UsingCombineTests/Mock.swift

    enhancement 
    opened by heckj 13
  • Unable to match mock with same url, headers and method with Alamofire

    Unable to match mock with same url, headers and method with Alamofire

    I'm having trouble matching a mock I create with the corresponding actual request being generated from an Alamofire requst, where the url, headers and method all match.

    Here's my mock setup:

    public final class MockedSeriesData {
        public static let exampleJSON: URL = Bundle(for: MockedSeriesData.self).url(forResource: "exampleSeriesList", withExtension: "json")!
    }
    
    class SeriesSupportTests: XCTestCase {
            let configuration = URLSessionConfiguration.default
            configuration.protocolClasses = [MockingURLProtocol.self]
            let sessionManager = SessionManager(configuration: configuration)
            
            let originalURL = SeriesSupport.getSeriesListURL()
            let expectation = self.expectation(description: "getAllSeries()")
            
            if let url = originalURL {
                print("Mock URL: \(url)")
                print("Mock URL (absolute): \(url.absoluteString)")
                let mock = Mock(url: url, contentType: .json, statusCode: 200, data: [
                    .get : MockedSeriesData.exampleJSON.data 
                ])
                Mocker.register(mock)
                SeriesSupport.getAllSeries(sessionManager: sessionManager, oktaHelper: oktaHelper) { seriesOption, errorOption in
                    expectation.fulfill()
                    // Evaluate result of completionHandler 
            } else {
                XCTFail( "Unable to unwrap Series List URL" )
            }
            
            waitForExpectations(timeout: 10) { error in
                if let error = error {
                    print("Error: \(error.localizedDescription)")
                }
            }
        }
    }
    
    • I thought maybe I was failing because my headers weren’t matching, so I removed the headers and still wasn’t getting a match.
    • I replaced our actual endpoint with , but I have validated it is exactly the same in all print statements

    Here’s the real actual Alamofire request:

    static let PODCAST_SERVICE_BASE_URL_PREFIX = "https://<host>/dev/podcast/"
        static let SERIES_SERVICE_ENDPOINT_SUFFIX = "series"
    
        class func getSeriesListURL() -> URL? {
            return URL(string: SERIES_SERVICE_ENDPOINT_SUFFIX, relativeTo: URL(string: PODCAST_SERVICE_BASE_URL_PREFIX))
        }
    
        class func getAllSeries( sessionManager: Alamofire.SessionManager=Alamofire.SessionManager.default, oktaHelper: OktaAuthSupport=OktaAuthHelper() ) {
            if let url = getSeriesListURL() {
                print("URL: \(url)")
                print("URL (absolute): \(url.absoluteString)")
                sessionManager.request(url, method: .get, headers: HTTPHeaders()).responseJSON { response in
                    switch response.result {
                    case .success(let value):
                        let json = JSON(value)
                        print("JSON: \(json)")
                        // Convert JSON to array and call completion handler with array
                    case .failure(let error):
                        print(error)
                        // Call completion handler with error
                    }
                }
            }
        }
    

    What is getting printed:

    Mock URL: series -- https://<host>/dev/podcast/
    Mock URL (absolute): https://<host>/dev/podcast/series
    
    URL: series -- https://<host>/dev/podcast/
    URL (absolute): https://<host>/dev/podcast/series
    

    And the error I get from Mocker:

    com.apple.CFNetwork.CustomProtocols (10): Fatal error: No mocked data found for url Optional("https://<host>/dev/podcast/series") method Optional("GET"). Did you forget to use register()?
    

    If I step into the Mocker code, I see my mock registered, but I can't step into the == check where it is evaluating a match on the request to see what is actually getting compared.

    Any help would be greatly appreciated!

    Frank

    opened by fporcaro 12
  • Support collection types as a top level object

    Support collection types as a top level object

    As you know, top level collection objects are also valid JSON. But, Mocker wasn't support them because of the casting that made up in the MockingURLProtocol.swift

    opened by batuhansk 11
  • RequestError: doesn't mock the error that's passed in and always return sessionTaskFailed

    RequestError: doesn't mock the error that's passed in and always return sessionTaskFailed

    I want to test our error handling and was hoping to use Mocker for it. We use Alamofire (but the bug is reproducible with URLSession).

    Without Alamofire (pseudo code)

                        var url: URL!
                        var urlSession: URLSession!
    
                        beforeEach {
                            let configuration = URLSessionConfiguration.default
                            configuration.protocolClasses = [MockingURLProtocol.self]
                            urlSession = URLSession(configuration: configuration)
    
                            let error = ResponseError.testError
                            url = URL(string: "https://test.mycompany.com/thisisvalid?key=hello")!
                                                    
                            mock = Mock(url: url, ignoreQuery: true, dataType: .json, statusCode: 404, data: [.get: Data()], requestError: error)
                            mock.register()
                        }
    
                        it("should call completion with correct error") {
                            waitUntil(timeout: .seconds(2)) { done in
                                urlSession.dataTask(with: url) { (data, response, error) in
                                    debugPrint("this error is: \(error as Optional)")
    
    // assertions on actions based on error
                                    done()
                                }.resume()
                            }
                        }
    

    po error

    ResponseError Code=0 "(null)" UserInfo={_NSURLErrorRelatedURLSessionTaskErrorKey=(
        "LocalDataTask <xxxx>.<1>"
    ), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <xxxx>.<1>}
    

    ^ this should have been the error I passed but instead I received a .sessionTaskFailed error.

    I did spend some time looking into this and the finishRequest inside MockingURLProtocol does get the mock.requestError properly but from there i'm not sure where it goes.

    In the actual project i'm using Alamofire but there too i'm getting similar error. The requestError in that case was let error: AFError = AFError.responseValidationFailed(reason: .unacceptableStatusCode(code: 404)).

    the returned error is

    ▿ Optional<Error>
      - some : Error Domain=Alamofire.AFError Code=9 "(null)" UserInfo={_NSURLErrorRelatedURLSessionTaskErrorKey=(
        "LocalDataTask <xxxx>
    ), _NSURLErrorFailingURLSessionTaskErrorKey=LocalDataTask <xxxx>
    
    Stale 
    opened by iOSDeveloperL 9
  • Linux support

    Linux support

    These extra imports allow to use the library in tests on Linux. As an example I've enabled Linux tests in kean/Get library.

    Also, removed unrelated warning that swift build showed:

    Mocker.swift:79:21: warning: result of call to 'registerClass' is unused
            URLProtocol.registerClass(MockingURLProtocol.self)
                        ^            ~~~~~~~~~~~~~~~~~~~~~~~~~
    
    opened by vox-humana 7
  • Only link XCTest weakly for CocoaPods

    Only link XCTest weakly for CocoaPods

    Resolves #94

    Not requiring this weakly means it'll attempt to load on every run; but XCTest will not be available when running the application directly.

    What did I do to test this?

    • run pod spec lint Mocker.podspec to verify the podspec passes validation
     -> Mocker (2.5.3)
        - NOTE  | xcodebuild:  note: Using new build system
        - NOTE  | xcodebuild:  note: Building targets in parallel
        - NOTE  | xcodebuild:  note: Using codesigning identity override: -
        - NOTE  | xcodebuild:  note: Build preparation complete
        - NOTE  | [iOS] xcodebuild:  note: Planning build
        - NOTE  | [iOS] xcodebuild:  note: Analyzing workspace
        - NOTE  | [iOS] xcodebuild:  note: Constructing build description
        - NOTE  | [iOS] xcodebuild:  warning: Skipping code signing because the target does not have an Info.plist file and one is not being generated automatically. (in target 'App' from project 'App')
    
    Analyzed 1 podspec.
    
    Mocker.podspec passed validation.
    
    • integrated the local build into a new project using
    pod 'Mocker', :path => '~/Path/To/Mocker.podspec'
    
    • verified that this does not crash at runtime
    • verified that this does not crash when importing Mocker, and using its APIs in a test bundle
    • verified that XCTest is no longer "always" required in the linked frameworks and libraries that CocoaPods generates.
    opened by BasThomas 7
  • Improve test expressivity

    Improve test expressivity

    Using specific assert functions will generate easier to understand failure messages if the tests were to fail. For example, in the XCTAssertNil case, it will say "something was unexpectedly not nil" instead of only "test failed".

    opened by BasThomas 7
  • Optional dataType

    Optional dataType

    As discussed in https://github.com/WeTransfer/Mocker/issues/134

    I've also added an additional initializer to simplify the mock creation in case a single non-get request has to be mocked.

    opened by chkpnt 6
  • Feature request: ignoring domains/subdomains or URL prefix

    Feature request: ignoring domains/subdomains or URL prefix

    Hey 👋

    I constantly see Mocker warnings about not mocking 3rd party URLs such as from mixpanel or Realm. The problem is that the URLs look like:

    https://api.mixpanel.com/track/?data=eyJldmVudCI………redacted-for-brevity-but-it's-a-really-long-url-jBkYmQ3ODzeCJ9fQ==&ip=1
    
    https://static.realm.io/update/cocoa?x.y.z // where x.y.z is my Realm library version
    

    Thus I thought if I called:

    Mocker.ignore(URL(string: "https://static.realm.io")!)
    

    That Mocker would ignore all requests within this domain, but it doesn't.

    I'd like to be able to ignore calls to realm.io or mixpanel.com (perhaps even omitting static. or api. for instance), or at least https://static.realm.io and https://api.mixpanel.com.

    I'm aware of a function to ignore all URLs but really doesn't accomplish the goal because I like the warnings for all requests that are from my own application.

    What are the challenges around implementing this? Are there any risks?

    Appreciate all the help!

    enhancement 
    opened by rogerluan 11
Releases(3.0.1)
Owner
WeTransfer
WeTransfer
Automatic testing of your Pull Requests on GitHub and BitBucket using Xcode Server. Keep your team productive and safe. Get up and running in minutes. @buildasaur

Buildasaur Automatic testing of your Pull Requests on GitHub and BitBucket using Xcode Server. Keep your team productive and safe. Get up and running

Buildasaurs 774 Dec 11, 2022
A flexible mock server for automated and regression testing of iOS, Android and other apps.

Note: This document is intended as a quick introduction to Voodoo. As Voodoo has a large number of features, please refer to Voodoo's Github Wiki for

Derek Clarkson 7 Nov 23, 2022
🐤Dynamically Mock server behaviors and responses in Swift

Kakapo Dynamically Mock server behaviors and responses. Contents Why Kakapo? Features Installation Usage Serializable protocol Router: Register and In

DevLucky 764 Aug 23, 2022
MockSwift is a Mock library written in Swift.

Welcome to MockSwift MockSwift allows you to write mocks and make better tests. Because MockSwift is an open source library 100% written in Swift, it

Jordhan Leoture 82 Dec 17, 2022
A Popover that mock iOS SkinTone Selection Popover.

IMessage SkinTone Popover This is a popover mock the iOS iMessage Skin Tone Selection Menu (Popover) Features Long press to invoeke the popover, and t

Vincent Liu 1 Dec 9, 2021
An elegant library for stubbing HTTP requests with ease in Swift

Mockingjay An elegant library for stubbing HTTP requests in Swift, allowing you to stub any HTTP/HTTPS using NSURLConnection or NSURLSession. That inc

Kyle Fuller 1.5k Dec 3, 2022
Test task application based on Swift using CoreData, Alamofire, AlamofireImage and CocoaPods

iTunes Search Test task application based on Swift using CoreData, Alamofire, AlamofireImage and CocoaPods Features ?? Searching music albums by name

Alexander Zhukov 0 Oct 31, 2021
Testing the UI without UI Testing, a Swift experiment.

UI tests without UI Testing experiment This repo is a small experiment to see if there's an "in-between" for testing iOS applications. More feature-le

Joe Masilotti 20 Sep 26, 2022
Lightweight touch visualization library in Swift. A single line of code and visualize your touches!

TouchVisualizer is a lightweight pure Swift implementation for visualising touches on the screen. Features Works with just a single line of code! Supp

Morita Naoki 851 Dec 17, 2022
This repository accompanies Test-Driven Development in Swift: Compile Better Code with XCTest and TDD

Apress Source Code This repository accompanies Test-Driven Development in Swift: Compile Better Code with XCTest and TDD by Gio Lodi (Apress, 2021). D

Apress 57 Jan 1, 2023
Take home task from one company developed on VIPER, UI Through code and splash from plist

HelloFresh Dev Team - Mobile iOS Developer Test Hello! Thank you for taking the time to try our iOS test. The goal of the test is to assess your codin

Jawad Ali 4 Aug 13, 2022
TestSchedulerDemo - Demonstration code for iOS Unit Tests and Asynchronous

TestSchedulerDemo This repository contains demonstration code for my Medium arti

Carsten Wenderdel 0 Mar 19, 2022
Detailed explanations and implementations of various maths concepts for writing high performance code/algorithms backed with Unit tests.

Detailed explanations and implementations of various maths concepts which can help software Engineers write high performance code/algorithms backed with Unit tests.

Mussa Charles 2 Sep 25, 2022
This repo holds the code for Dubizzle & Bayut test App

DubizzleClassified This repo holds the code for Dubizzle & Bayut test App About App This is a simple app which basically fetches item list from the gi

Ghassan 0 Jun 2, 2022
Code coverage for Xcode projects (Objective-C only)

XcodeCoverage provides a simple way to generate reports of the Objective-C code coverage of your Xcode project. Generated reports include HTML and Cob

Jon Reid 854 Dec 19, 2022
PinpointKit is an open-source iOS library in Swift that lets your testers and users send feedback with annotated screenshots using a simple gesture.

PinpointKit is an open-source iOS library in Swift that lets your testers and users send feedback with annotated screenshots using a simple gesture. F

Lickability 1.1k Jan 6, 2023
View your app on different device and font sizes

Sizes reduces the time it takes to evaluate all of our apps possible device sizes, orientations and font combinations. With Sizes we'll avoid launchin

Marcos Griselli 1.2k Oct 27, 2022
Switchboard - easy and super light weight A/B testing for your mobile iPhone or android app. This mobile A/B testing framework allows you with minimal servers to run large amounts of mobile users.

Switchboard - easy A/B testing for your mobile app What it does Switchboard is a simple way to remote control your mobile application even after you'v

Keepsafe 287 Nov 19, 2022
AutoMocker is a Swift framework that leverages the type system to let you easily create mocked instances of your data types.

AutoMocker Context AutoMocker is a Swift framework that leverages the type system to let you easily create mocked instances of your data types. Here's

Vincent Pradeilles 39 May 19, 2022