GithubHelp home page GithubHelp logo

kylef / mockingjay Goto Github PK

View Code? Open in Web Editor NEW
1.5K 1.5K 178.0 396 KB

An elegant library for stubbing HTTP requests with ease in Swift

License: BSD 3-Clause "New" or "Revised" License

Ruby 3.17% Swift 94.20% Objective-C 2.64%

mockingjay's Introduction

Curassow

Build Status

Curassow is a Swift Nest HTTP Server. It uses the pre-fork worker model and it's similar to Python's Gunicorn and Ruby's Unicorn.

It exposes a Nest-compatible interface for your application, allowing you to use Curassow with any Nest compatible web frameworks of your choice.

Documentation

Full documentation can be found on the Curassow website: https://curassow.fuller.li

Usage

To use Curassow, you will need to install it via the Swift Package Manager, you can add it to the list of dependencies in your Package.swift:

import PackageDescription

let package = Package(
  name: "HelloWorld",
  dependencies: [
    .Package(url: "https://github.com/kylef/Curassow.git", majorVersion: 0, minor: 6),
  ]
)

Afterwards you can place your web application implementation in Sources and add the runner inside main.swift which exposes a command line tool to run your web application:

import Curassow
import Inquiline


serve { request in
  return Response(.ok, contentType: "text/plain", body: "Hello World")
}

Then build and run your application:

$ swift build --configuration release

Example Application

You can find a hello world example application that uses Curassow.

License

Curassow is licensed under the BSD license. See LICENSE for more info.

mockingjay's People

Contributors

antigp avatar blackm00n avatar felixclack avatar hellostu avatar hiroraba avatar iamdecode avatar itszero avatar j-j-m avatar klaaspieter avatar kylef avatar modocache avatar neonichu avatar nwest avatar shams-ahmed avatar teameh avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mockingjay's Issues

URITemplate Broke

Hi URITemplate is not yet compatible with swift 1.2. Can you link to the new version in pod spec when it comes out?

Xcode can't find stub or matcher now

We have jsonData now but now Xcode is complaining that stub and matcher are unavailable. Not sure why.

import Foundation
import Mockingjay

class TestModel: NSObject {

    class func testRequest() {
        let path = NSBundle.mainBundle().pathForResource("Plaid", ofType: "json")
        let data = NSData(contentsOfFile: path!)!

        stub(matcher, builder: jsonData(data))
    }

}

Ideas?

screen shot 2015-10-12 at 10 51 24 am

Find out if URL was requested

Feature request:

I'd like to know whether my stubbed URL is requested.
I imagine this could work something like this:

let body = [ "description": "Kyle" ]
let userStub = stub(http(.PUT, uri: "/kylef/Mockingjay"), json(body))

expect(userStub.requested).toEventually(beTrue())

Since this doesn't work, I came up with a solution using a custom matcher:

///  Creates a custom matcher that calls the requestMatchedHandler when a request was succesfully matched
func matcher(_ method: HTTPMethod, uri: String, requestMatchedHandler: @escaping () -> Void) -> (_ request: URLRequest) -> Bool {
    let matcher = http(method, uri: uri)
    return { (request: URLRequest) in
        let result = matcher(request)
        if result {
            requestMatchedHandler()
        }
        return result
    }
}

var requestMatched = true

let body = [ "description": "Kyle" ]
stub(http(.PUT, uri: "/kylef/Mockingjay", requestMatchedHandler: { () in
    requestMatched = true
}), json(body))

expect(requestMatched).toEventually(beTrue())

Compare query parameters (ignoring order)

I think it'd be useful to have a matcher (or change uri) to compare query parameters ignoring their order. I was able to implement that with a custom matcher:

func uriWithQuery(uriString:String) -> (request:NSURLRequest) -> Bool {
    return { (request:NSURLRequest) in
        if uri(uriString)(request: request) {
            return true
        }

        if let components = NSURLComponents(string: uriString),
            requestComponents = request.URL.flatMap({ NSURLComponents.init(URL: $0, resolvingAgainstBaseURL: false)}) {
            let componentsWithoutParams = components.copy() as! NSURLComponents
            componentsWithoutParams.query = nil

            let requestComponentsWithoutParams = requestComponents.copy() as! NSURLComponents
            requestComponentsWithoutParams.query = nil

            if requestComponentsWithoutParams.URL == componentsWithoutParams.URL {
                return requestComponents.queryItems.flatMap(Set.init) == components.queryItems.flatMap(Set.init)
            }
        }

        return false
    }
}

Note that this probably doesn't support path templates.

Outdated readme.md: using PUT instead of put

Example from readme:

stub(http(.PUT, "/kylef/Mockingjay"), json(body))

Current version of Alamofire uses .put, not .Put. Example is also missing uri label. This produces compilation errors.

Swift 4 Support - Podspec update

I see the changes for Swift 4 have been made. However, the pod spec hasn't been updated so this refactor remains unavailable on Cocoapods.

Tries to load library to wrong target

I'm developing a framework in swift, I'm using Carthage for dependency management. When I add Mockingjay to the test target my tests work, but when I try to build an app with my framwork i get

dyld: Library not loaded: @rpath/Mockingjay.framework/Mockingjay

Which is strange, as Mockingjay is only added to the test target.

Reproducible example can be found at:

https://github.com/tapglue/ios_sdk/tree/mockingjay

Open-source

  • Open-source repository
  • Enable travis
  • Push podspec

Add support for Swift 3/Xcode 8

I've attempted to convert the project over using the Xcode 8 refactor tool, and fixed a few things manually. I am having trouble with the MockingjayAsyncProtocolTests. Those tests will show a number 2-second timeout messages, and then just seems to sit there and not won't complete the test. All of the other tests pass fine.

My code is on my fork, adamdebono/Mockingjay@bfc0e71

(Also I have pointed URITemplate to my own fork which has also been updated to Swift 3 as well)

Matchers running slowly

I've got a test that's a sort of integration/stress test for my networking code. When I switched from having my networking code check for cached files my tests placed in a temp directory to using Mockingjay, the tests slowed down a lot. I profiled with Instruments, and found that most of the test's time is being spent in MockingjayProtocol.stubForRequest(NSURLRequest) -> Stub?, and specifically in my custom matcher, which looks like this:

public func urlPathEquals(path: String) -> (request:NSURLRequest) -> Bool {
    return { request in
        request.URL?.path == path
    }
}

Before this test case runs, I loop through my large number of JSON files and create a matcher like this for each one, so there is a large number of mocks configured. What can I do to speed this up? My test is taking so long that it's causing a failure on my build server.

NSURLSessionConfiguration swizzling with Alamofire

This is a strange one. Mockingjay's initialize() on XCTest is working as expected but the one on NSURLSessionConfiguration never actually fires.

The swizzle hooks properly if you manually call NSURLSessionConfiguration.initialize(), otherwise MockingjayProtocol never gets pushed into protocolClasses in the configuration.

Xcode 7.0 (7A220)
Alamofire 2.0.0

Here's the relevant code on Alamofire.

Simulate delay of responses

Is there any builtin functionality to add a delay to the responses, in order to simulate a real server hit?

I find it really useful for both automated UI tests and during development, in case I want to check the "loading" status with a controlled response.

Cannot stub a uri without complete url scheme

Using mockingjay to stub api calls that can be done on any baseUrl, I am doing this:
self.stub(http(.PUT, uri: "/session/{session_id}/rate?user_id={user_id}"), builder: http(400))

This does not work, I need to do this:
self.stub(http(.PUT, uri: "http://demo.usievents.com/api/v1/session/42/rate?user_id=42"), builder: http(400))

Digging into URITemplate.swift, it seems you add a "^" in front of the regex, thus it expects the matching to occurs on first character.

request.HTTPBody is always nil in custom matcher

I'm setting the HTTPBody property of an NSMutableURLRequest and trying to do some comparison on it inside of a custom matcher.

However, the property's value is always nil by the time the request reaches the matcher despite it being set prior to that.

Using Mockingjay in app target (no XCTest)

I want to use Mockingjay in my app to stub real APIs while they are still in development, so I tried what @kylef suggested in #28, but it is not working because you also need to swizzle the NSURLSessionConfiguration (as the implementation in Mockingjay/XCTest does).

The final replacement stub method should be:

func stub(matcher:Matcher, builder:Builder) -> Stub {
    NSURLSessionConfiguration.mockingjaySwizzleDefaultSessionConfiguration()    
    return MockingjayProtocol.addStub(matcher, builder: builder)
}

Since using Mockingjay without XCTest could be a useful scenario, maybe it is worth having a note in the readme, or even better supporting this natively.

Another issue is that using the full Mockingjay pod in a test target while using Mockingjay/Core pod in the app creates conflicts on compilation, since if you include both pods they will be compiled as a single framework, I guess (maybe Cocoapods error?).
In my opinion, the stub method should be moved to another global place (like Mockingjay.stub), so that it would be available regardless of XCTest, while the XCTest stuff should be moved to a separate framework or even removed entirely, since it is so simple (and much more clear) to just add a removeAllStubs on tearDown method in a test case, like OHHTTPStubs does.

Preventing unintended network requests for unmatched requests

In my current use of Mockingjay I find that if my implementation is somehow incorrect and the matcher returns false, actual network requests are made.

This is all working as expected, but I would prefer it if no networks requests were made, and any unintended requests cause a test to fail.

Is this somehow possible already? If not, I think something like an everythingExcept matcher could be useful.

Add example project

Is it possible to add an example project to see how to setup a complete project? At the moment it is not very clear how to use Mockingjay which will prevent many developers from using it.

Can I mock language headers?

Can I use this lib mock "Accept-Language" with "en-US;q=1.0" value rather than the system (iphone or MAC) value?
Thanks a lot.

Problem using MockingJay

I have a model class that fetches data from my server using AlamoOnFire, ObjectMapper and Realm for persistance. Realm introduces the List construct.

My problem is that MockingJay doesn't seem to be used. The JSON-File from the file-system can be loaded in my test and contains the data that is computed correctly if fetched from server.

Any idea what could be wrong?

import XCTest
import Mockingjay
import RealmSwift
@testable import MyApp

class OverviewModelTests: XCTestCase {

    override func setUp() {
        super.setUp()
        let path = NSBundle(forClass: self.dynamicType).pathForResource("Overview", ofType: "json")!
        let data = NSData(contentsOfFile: path)!
        stub(everything, builder: jsonData(data))
    }
    //http(.GET, uri: URLs.sharedInstance.overviewItemsUrl())


    func testFetchOverviewItems() {

        let overviewModel = OverviewModel()

        overviewModel.fetchOverviewItemList({ (itemList: List<OverviewItem>) -> () in

            XCTAssertTrue(itemList.count == 6)
            })
            { (error: ErrorType?) -> () in
                XCTFail("Error in testFetchOverviewItems ")
            }
    }


}

Add instructions how to install using Carthage

Thank you for this great project. I was thinking about doing this myself.

I don't want to use CocoaPods. Could you please add instructions how to install it manually of using Carthage.

I tried to build it using Carthage but it didn't work. The compiler doesn't find 'stub'.

tvOS 10+ Support

Hi everyone,

I'm currently implementing unit tests on my tvOS application and I'd like to mock HTTP requests from Apollo (GraphQL Client). I already use Mockingjay on my iOS app and I'd love to use it aswel for tvOS.

My question is quite simple, is a tvOS support coming ?

Thanks in advance for your help guys.
Btw, thanks also for your work!

Regards

Getting Library not loaded

I'm getting the following error in the console but am at a miss to fix it.
Can someone help?

dyld: Library not loaded: @rpath/XCTest.framework/XCTest
  Referenced from: /Users/Dev/Library/Developer/Xcode/DerivedData/test-hehyhfozbszkqvgifetexjhfsqsz/Build/Products/Debug-iphonesimulator/Mockingjay.framework/Mockingjay
  Reason: image not found

jsonData in Pod release

Hey Kyle,

Great work. Just wanted to point out that the jsonData builder isn't in the CocoaPod release, in case you didn't know.

Thanks

Add example project

Is it possible to add an example project to see how to setup a complete project? At the moment it is not very clear how to use Mockingjay which will prevent many developers from using it.

Swift 3 + Alamofire 4

Tests were failing which was due to Alamofire’s SessionManager’s URLSessionConfiguration not having MockingjayProtocol in its list of URLProtocol classes. Turns out the swizzler was never being called. I fixed this in a fork.

Not sure if you had already planned on fixing this or had something else in mind to address it.

Carthage support

I'm just wondering if this project is open to putting official support for Carthage. Perviously it was possible to get Mockingjay (sort of) working with Carthage just by adding both Mockingjay and URITemplate to the Cartfile.

But moving to Swift 3 support and this no longer works.

One of the reasons is that URITemplate has now removed the Xcode project file for the repo which Carthage relies on to build the framework. This means that if we are going to add Carthage support for this, we will probably need to restore the project file in the URITemplate repo.

The other issue is that, as I mentioned above, the previous method only sort of worked. I'm not 100% sure on this, but because this repo includes URITemplate as a submodule, when Carthage checkouts/clones this repo as a dependency, it also checkouts the URITemplate submodule. So I think that when the project is built, it is using the commit/version of URITemplate that the submodule points to. Then when used in our test target, it uses a different version of URITemplate framework which is built using the commit/version that is resolved by Carthage (which might no necessarily be the same as the one that is pointed to by the URITemplate submodule in this repo).

TBH, I'm not necessarily sure what the best way is to resolve the issue above. A solution might involve changing the location of the URITemplate project to the Carthage/Checkout/URITemplate path, and using Carthage to checkout the dependencies before building the project in Xcode.

Thoughts?

dyld: lazy symbol binding failed: Symbol not found

I have been using Mockingjay in XCTest very well. However recently I noticed that if I can use it in main target, it would be nice. So I changed Podfile like this:

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

inhibit_all_warnings!

target 'Surfline' do
    pod 'Mockingjay/Core'

    target 'SurflineTests' do
        pod 'Mockingjay/XCTest'
    end
end

And it worked very well with main target but I stuck in test.

I have this line in my test

@testable import MainTarget

I need this for not to change access level of class properties in the main target. Tests without the line is perfectly fine but with the line it shows error:

dyld: lazy symbol binding failed: Symbol not found: __TFE10MockingjayCSo6XCTest4stubfTFV10Foundation10URLRequestSbFS2_OS_8Response_VS_4Stub
  Referenced from: /Users/rhan/Library/Developer/Xcode/DerivedData/Surfline-eheubjimlqgiykerufbqqnwywuhs/Build/Intermediates/CodeCoverage/Products/Debug-iphonesimulator/Surfline.app/PlugIns/SurflineTests.xctest/SurflineTests
  Expected in: /Users/rhan/Library/Developer/CoreSimulator/Devices/9C5026F0-B25E-40C1-99FB-0E1F63FAFC3F/data/Containers/Bundle/Application/734A040B-E1D2-45F8-93A4-3ADFA837010B/Surfline.app/Frameworks/Mockingjay.framework/Mockingjay

dyld: Symbol not found: __TFE10MockingjayCSo6XCTest4stubfTFV10Foundation10URLRequestSbFS2_OS_8Response_VS_4Stub
  Referenced from: /Users/rhan/Library/Developer/Xcode/DerivedData/Surfline-eheubjimlqgiykerufbqqnwywuhs/Build/Intermediates/CodeCoverage/Products/Debug-iphonesimulator/Surfline.app/PlugIns/SurflineTests.xctest/SurflineTests
  Expected in: /Users/rhan/Library/Developer/CoreSimulator/Devices/9C5026F0-B25E-40C1-99FB-0E1F63FAFC3F/data/Containers/Bundle/Application/734A040B-E1D2-45F8-93A4-3ADFA837010B/Surfline.app/Frameworks/Mockingjay.framework/Mockingjay

I'm stuck here. Any hint will be very appreciated.

Minimum deployment target 9.1 error Xcode 7.1

I've just upgraded my Xcode to 7.1 and I'm no longer being able to build Mockingjay due to the following error: Module file's minimum deployment target is ios9.1 v9.1:
Do you have any idea how to fix this?
Thanks.

CocoaPods update

Hi @kylef
please push recent changes to cocoapods. It would be much help in my future tests :)

Turn ENABLE_BITCODE = YES for watchOS result in compilation errors.

In mockingjay.xcconfig, turn ENABLE_BITCODE = YES. Turn bitcode on for all the other targets in the project too. This is required for watchOS. Please resolve this because it is a show stopper for us.

Get compilation error:

ld: '/Users/nyan/Library/Developer/Xcode/DerivedData/zipcar-bjuclsirfazpdbhbekejanyrfonv/Build/Products/Debug-iphoneos/Mockingjay/Mockingjay.framework/Mockingjay' does not contain bitcode. You must rebuild it with bitcode enabled (Xcode setting ENABLE_BITCODE), obtain an updated library from the vendor, or disable bitcode for this target. for architecture arm64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Carthage - Mockingjay for iOS

I use Carthage and it uses shared schemes to build dependencies but there is only a target for Mac OS X, could iOS be added so it works with Carthage?

Offer JSON Schema validation

Making use of JSONSchema to provider a matcher.

This might look something like:

let schema = Schema([
    "type": "object",
    "properties": [
        "name": ["type": "string"],
        "price": ["type": "number"],
    ],
    "required": ["name"],
])

let matcher = allOf([
    uri('/'),
    json(schema),
])
stub(matcher, response)

Empty Body

How can i stub a request with only status code? Without body.

I've been trying to do that but with no success.

I did this

stub(http(method.toMockingjay(), uri: endpointPath), http(401))

And a do need to get the statusCode but the DataResponse.response from Alamofire is always nil

Isn't better use URITemplate 2.0.0 in last tag?

In 1.3.0 release and master branch you're using URI Template 2.0.0, but when I use the last tag (1.3.1) the URITemplate dependency used is 1.4.0. Isn't better use also version 2.0.0 in last tag?

Tag 1.0.0 Release

I'm sure you'll find this issue a doddle to fix!

I'm having trouble using v1.0.0 via CocoaPods because there's no 1.0.0 tag on this repository.

Just in case you need this, this is what pod install says:

[!] Error installing Mockingjay
[!] /usr/local/bin/git clone https://github.com/kylef/Mockingjay.git /var/folders/1f/j5dkbzz11wq7r6wpy0zl38t00000gn/T/d20150922-6859-12gu0sb --single-branch --depth 1 --branch 1.0.0

Cloning into '/var/folders/1f/j5dkbzz11wq7r6wpy0zl38t00000gn/T/d20150922-6859-12gu0sb'...
warning: Could not find remote branch 1.0.0 to clone.
fatal: Remote branch 1.0.0 not found in upstream origin

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.