Giter Club home page Giter Club logo

nocilla's People

Contributors

ajimix avatar alloy avatar autoc0diq avatar ayanonagon avatar benblakely avatar bencevans avatar chrisdevereux avatar e-kazakov avatar fillito avatar ileitch avatar jeanregisser avatar kayvink avatar luisobo avatar mau888 avatar mjholgate avatar modocache avatar netbe avatar pietbrauer avatar robb avatar sjmadsen avatar stigi avatar swizzlr avatar timshadel avatar tonyarnold avatar vikingosegundo avatar ychang-brightcove 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

nocilla's Issues

Reliance on `libPods.a`?

I've not come across this library before, and it's not included with the project — I assume it's CocoaPods? The project does not currently compile on a straight clone for me.

Please don't make CocoaPods a requirement for using this project, as I'm sure that I'm not alone in preferring not to use CocoaPods in my work.

Match only the stubbed request?

I'm starting using Nocilla and it's very cool. Unfortunately I have the same issue as issue 49.
The application makes some http request directed to https://gsp-ssl.ls.apple.com/revgeo.arpc and I'm forced to mock event these calls.

    stubRequest(@"POST", @"https://gsp-ssl.ls.apple.com/revgeo.arpc").
    withHeaders(@{ @"x-Apple-gs1": @"13" }).
    withBody(@"(null)");

There is a way to catch only the stubbed calls and ignore all the others?

Add support for mocking requests

I'd like to see support for mocking requests - I want to test that in a given situation, a request is not sent to the server.

Define the number of times a stubbedRequest can be hit

In my use case, I would like to ensure that I only hit a specific URL one time, and if it hits it again, I would like to fail the test. Should be pretty simple, and I may implement it and submit it as a pull request.

Expose isStarted?

Hi there! First off, I LOVE Nocilla. It makes stubbing HTTP requests awesome. Thank you so much for putting it into the world.

Second! I'm wondering if you would consider exposing the "isStarted" method in the public interface? I have some test helpers ("logIn:(NSString *)email password:(NSString *)password" and "logOut") that would benefit greatly from knowing if Nocilla has been started and, if not, starting it to stub out Gravatar URL requests.

I'm happy to fork / update / pull request if you'd like. Just let me know.

NocillaUnexpectedRequest seems to jam NSURLSession queue

I'm a bit confused about how the NocillaUnexpectedRequest exception is supposed to work. Is the idea that it should halt the execution of the entire test suite, or rather that it should just fail an individual test?

The reason I ask is that I am migrating my project from ASIHTTPRequest to NSURLSession, and I noticed some strange problems.

ASIHTTPRequest was silently swallowing the NocillaUnexpectedRequest exceptions, so they were never seen, although I suspect I was getting an error returned from the HTTP request. It didn't matter in my tests though, as those particular tests didn't rely on the result of the unstubbed request.

However, with NSURLSession, I found that once the exception fired, no further HTTP requests could be made, and simply timed out thus causing later tests to fail. I think what may be happening is that it ended up crashing the NSOperationQueue that was being used to executing the requests by NSURLSession.

I added a nasty hack (#102) to force the exception to be raised in the main thread to make it visible, however, this obviously halted the entire test suite.

My question is, is this a bug? What is the intended behaviour of a NocillaUnexpectedRequest exception being raised?

Add option to enable real HTTP requests

At this point, when Nocilla is enabled, any HTTP request will be handled by Nocilla and won't hit the outside world. This is the desired behavior for unit tests but disabling this behavior may be convenient for other scenarios.

pod install issues warning

Cloning the repo and running pod install issues the following warning:

modocache@modocache ~/Github/modocache/Nocilla (modocache@master) (´・ω ・`) pod install
Resolving dependencies of `./Podfile'
Resolving dependencies for target `default' (iOS 4.3)
Resolving dependencies for target `NocillaTests' (iOS 4.3)
Downloading dependencies
Installing AFNetworking (1.0RC1)
Installing CocoaAsyncSocket (0.0.1)
Installing CocoaHTTPServer (2.2.1)
Installing CocoaLumberjack (1.3.3)
Installing Kiwi (1.1.0)
Installing MKNetworkKit (0.85)
Installing Reachability (3.0.0)
Generating support files
Integrating `libPods.a' into target `Nocilla' of Xcode project `./Nocilla.xcodeproj'.

[!] The target `Nocilla [Debug - Release]' overrides the `OTHER_LDFLAGS' build setting defined in `Pods/Pods.xcconfig'.
    - Use the `$(inherited)' flag, or
    - Remove the build settings from the target.

modocache@modocache ~/Github/modocache/Nocilla (modocache@master) (´・ω ・`)

Support for RestKit

Hello!

I see in your docs:
"Supports NSURLConnection, NSURLSession and ASIHTTPRequest."

Do you support AFNetworking 1/2 and Restkit?

Thanks in advance.

Nocilla messing with Xcode/Simulators call home to Apple

Problem

Letting Unit tests run for a long time (approx 1-2 second) will trip Nocilla up, as something makes an unexpected http call for http://gsp1.apple.com/pep/gcc. That url is a service which gives the country code for calling IP.

I'm guessing that it's the Simulator which tries to locate which country it's in.

Setup

  • I'm using Xcode 5 DP6, running ordinary XCTests.
  • I'm using AFNetworking and Nocilla.

In order to be able to test asynchronous callbacks from AFNetworking I'm using the following macros

#define TestNeedsToWaitForBlock() __block BOOL blockFinished = NO
#define BlockFinished() blockFinished = YES
#define WaitForBlock() while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) && !blockFinished)
  1. Define the variable blockFinished
  2. After the block call, wait in a loop for the var to switch
  3. In the block itself, toggle the var blockFinished when we are actually finished

Result

If I run the test with out waiting for the block to execute, everything works fine.

If I wait, using the method described above, Nocilla stacktraces with the message below. The only URL I'm calling is a local server.

2013-09-09 09:56:53.005 APPNAME[77042:6ef3] *** Terminating app due to uncaught exception 'NocillaUnexpectedRequest', reason: 'An unexpected HTTP request was fired.

Use this snippet to stub the request:
stubRequest(@"GET", @"http://gsp1.apple.com/pep/gcc");
'
*** First throw call stack:
(
    0   CoreFoundation                      0x01b186f4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x018988b6 objc_exception_throw + 44
    2   CoreFoundation                      0x01b184cb +[NSException raise:format:] + 139
    3   APPNAMETests                        0x09b98ca5 -[LSNocilla responseForRequest:] + 901
    4   APPNAMETests                        0x09b97b98 -[LSHTTPStubURLProtocol startLoading] + 168
    5   Foundation                          0x015acdc2 __31-[_NSCFURLProtocolBridge start]_block_invoke + 59
    6   Foundation                          0x01514dd5 -[NSBlockOperation main] + 88
    7   Foundation                          0x0156dcb9 -[__NSOperationInternal _start:] + 671
    8   Foundation                          0x014ea9e8 -[NSOperation start] + 83
    9   Foundation                          0x015abdc3 -[_NSCFURLProtocolBridgeWithTrampoline processEventQ] + 291
    10  Foundation                          0x015ac472 -[_NSCFURLProtocolBridgeWithTrampoline pushEvent:from:] + 264
    11  Foundation                          0x015acd82 -[_NSCFURLProtocolBridge start] + 94
    12  Foundation                          0x015adf91 bridgeStart + 80
    13  CFNetwork                           0x03219cdb _ZN19URLProtocol_Classic28_protocolInterface_startLoadEPK20_CFCachedURLResponse + 65
    14  CFNetwork                           0x032436a3 ___ZN19URLConnectionLoader27_private_ScheduleOriginLoadEPK13_CFURLRequestPK20_CFCachedURLResponse_block_invoke_2 + 147
    15  CFNetwork                           0x032422e6 ___ZNK19URLConnectionLoader25withExistingProtocolAsyncEU13block_pointerFvP11URLProtocolE_block_invoke + 30
    16  CFNetwork                           0x032832ff ___ZNK17CoreSchedulingSet13_performAsyncEPKcU13block_pointerFvvE_block_invoke + 25
    17  CoreFoundation                      0x01ab9e89 CFArrayApplyFunction + 57
    18  CFNetwork                           0x031a287f _ZN19RunloopBlockContext7performEv + 139
    19  CFNetwork                           0x032838e2 _ZThn16_N19RunloopBlockContext24multiplexerClientPerformEv + 20
    20  CFNetwork                           0x031a26ad _ZN17MultiplexerSource7performEv + 299
    21  CFNetwork                           0x031a24c2 _ZN17MultiplexerSource8_performEPv + 76
    22  CoreFoundation                      0x01aa196f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    23  CoreFoundation                      0x01aa12fb __CFRunLoopDoSources0 + 235
    24  CoreFoundation                      0x01abe3ce __CFRunLoopRun + 910
    25  CoreFoundation                      0x01abdbf3 CFRunLoopRunSpecific + 467
    26  CoreFoundation                      0x01abda0b CFRunLoopRunInMode + 123
    27  Foundation                          0x01494e6e +[NSURLConnection(Loader) _resourceLoadLoop:] + 381
    28  Foundation                          0x014f0a27 -[NSThread main] + 76
    29  Foundation                          0x014f0986 __NSThread__main__ + 1275
    30  libsystem_c.dylib                   0x021dad37 _pthread_start + 344
    31  libsystem_c.dylib                   0x021c554e thread_start + 34
)
libc++abi.dylib: terminating with uncaught exception of type NSException

Add possibility to use dictionary in `withBody()`

When mocking requests containing a JSON body, it is kind of hard to set the correct body for the request.

It would be nice to be able to stub a request as follows:

stubRequest(@"GET", "http://some/url")
    .withBody(@{ @"required" : @"parameter" });

This method should verify that all defined keys are set in the request body and that the values of the keys are equal to the ones sent.

This of course means deserializing the request body but would make verifying the existence of only a subset of keys in a JSON request much more elegant.

Stub GET (or POST) params in different order

Hi,

I'm trying to stub a request with Nocilla, and I'm not sure that with regex should be enough to define path structure.
I mean, when you send GET or POST params, you don't need to send these params in any order, so regex isn't the same for GET: http://api.myhost.com/users?pagination=5&per_page=10 than for GET: http://api.myhost.com/users?per_page=10&pagination=5, but API response should be the same.

Should be interesting to have a dictionary with GET/POST params instead of a NSString and iterate over it instead of match exactly? If your answer is yes, I could start to work in my first PR to Nocilla :)

What do you think about that?

Not able to stub cookies

    stubRequest(@"GET", @"https://example.com/hello").
    andReturn(200).withBody(@"hola").
    withHeaders(@{@"Set-Cookie": @"giveme=cookies;Path=/;", @"Content-Type": @"text/plain"});

    NSURL *url = [NSURL URLWithString:@"https://example.com/hello"];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url];
    AFHTTPRequestOperation *operation = [[AFHTTPRequestOperation alloc] initWithRequest:request];
    [operation start];

    [operation waitUntilFinished];

    NSHTTPCookieStorage *cookieStorage = [NSHTTPCookieStorage sharedHTTPCookieStorage];
    NSArray *cookies = [cookieStorage cookiesForURL:[NSURL URLWithString:@"https://example.com/"]];
    NSHTTPCookie *cookie = cookies[0];
    [[[cookie name] should] equal:@"giveme"];
    [[[cookie value] should] equal:@"cookies"];

this unit test fails because it cannot read the cookie back from NSHTTPCookieStorage.

Inconsistently raising `NocillaUnexpectedRequest` exception

I've tried both the currently released and HEAD versions. Currently using the HEAD version.

This is a snip from my log:

2013-05-29 08:26:54.097 GRC_Consumer[34040:c07] Enabled View and Notification Observation. (<SparkInspector: 0x975b0a0>)
2013-05-29 08:26:54:100 GRC_Consumer[34040:c07] Application did finish launching with options: (null)
2013-05-29 08:26:54:101 GRC_Consumer[34040:c07] Setting up fixture data. 
...
2013-05-29 08:26:54.506 GRC_Consumer[34040:6a03] *** Terminating app due to uncaught exception 'NocillaUnexpectedRequest', reason: 'An unexcepted HTTP request was fired.

Use this snippet to stub the request:
stubRequest(@"GET", @"https://foo/bar").
withHeaders(@{ @"Accept": @"application/json", @"Accept-Language": @"en;q=1, fr;q=0.9, de;q=0.8, ja;q=0.7, nl;q=0.6, it;q=0.5", @"User-Agent": @"GRC_Consumer/1.0 (iPad Simulator; iOS 6.1; Scale/1.00)" });
'
*** First throw call stack:
(0x2364012 0x1c15e7e 0x2363deb 0xd18e0 0x1939a97 0x18a975a 0x1877453 0x1877164 0x1938a73 0x1939122 0x1939a57 0x193ad95 0x193ac9c 0x479e09 0x49e7f7 0x49c76c 0x4d5cda 0x23068fd 0x4d635c 0x4d62d5 0x3c0250 0x22e7f3f 0x22e796f 0x230a734 0x2309f44 0x2309e1b 0x19415ee 0x1889805 0x1889764 0x97db05b7 0x97d9ad4e)
libc++abi.dylib: terminate called throwing an exception
(lldb) 

Notice the line "Setting up fixture data". That is where I stub the request. Notice that it happens prior to getting the exception.

It is not every time I run either. However, I've not been able to detect any external cause. I suspect a timing error in Nocilla.

What can I do to help diagnose this?

specify CFNetwork dependency in podspec

Apparently LSResponseStub has a dependency on CFNetwork through CFHTTPMessage and the like.

You should specify that dependency in the podspec using s.ios.frameworks = 'CFNetwork'

And possibly it's worth an mention in the readme, too.

Add expectations

Nocilla only support stubbing but it doesn't support expectations on HTTP requests. It not often required, but it should be in there

AFNetworking not finding valid stubs

The problem seems to be in the LSStubRequest class in the individual matchesMethod:/matchesURL:/matchesHeaders:/matchesBody: methods.

Basically, request.method for AFNetworking is undefined, so the match will always fail. It needs to be [request method]. The same goes for the other items in the protocol:

  • request.url should be [request url]
  • request.headers should be [request headers]
  • request.body should be [reqeust body]

For some reason, it just is failing with using the dot notation.

Unit Testing for AFNetworking calls which are in my code

Hi,
I have read this article for unit testing API calls and I understood the concept of unit testing with mock objects to test API calls.
http://www.infinite-loop.dk/blog/2011/09/using-nsurlprotocol-for-injecting-test-data/
Inside code of above article sample

[self loadCannedResultWithName:@"MiddleOfNowhere"];
mockParser = [OCMockObject partialMockForObject:parser];
[[[mockParser stub] andCall:@selector(returnCannedResultForRequest:)
onObject:self] sendRequestWithURLString:[OCMArg any]];

// Perform code under test
[parser findNearbyPlaceNameForLatitude:-10.0 longitude:-10.0];

// Validate result
STAssertTrue([self waitForCompletion:3.0], @"Failed to get any results in time");
STAssertNotNil(searchResult, @"Didn't expect an error");
STAssertEquals([searchResult count], (NSUInteger)0, @"Should not find any results in the middle of nowhere: %@", searchResult);
STAssertEquals(totalFound, 0U, @"Unexpected number of total results");

It calls that method which is in my code and under test
// Perform code under test
[parser findNearbyPlaceNameForLatitude:-10.0 longitude:-10.0];

above method is in code file rather than test class but when I look at Nocilla samples, it does not call actual methods of code. It samples are all in test file and independent of method which I actually want to test.
My goal is to test a webservice call, validate its url, host etc, body parameters and only mock that part which interact with live server. How can I achieve that.

Thanks in advance.

Report unexpected requests properly

If some request is made but it wasn't stubbed, Nocilla won't let that request hit the real world. In that case your test should fail.
At this moment Nocilla will return a response with a 500, the header X-Nocilla: Unexpected Request and a body with a meaningful message about the error and how to solve it, including a snippet of code on how to stub the unexpected request.

Raising an exception wasn't working well with Kiwi, it didn't report failure.

The correct way of doing this is to integrate with test runners to make the current spec fail.

Problem stubbing a JSON request with AFNetworking 2

I'm just starting to use Nocilla to stub some of the requests to our JSON API and I keep getting an unexpected request thrown exception.

The exception message shows:

'NocillaUnexpectedRequest', reason: 'An unexpected HTTP request was fired.

Use this snippet to stub the request:
stubRequest(@"GET", @"http://sally-api.dev/api/users/sign_in?email=zaid%40place.ca&password=secret").
withHeaders(@{ @"Accept-Language": @"en;q=1, fr;q=0.9, de;q=0.8, zh-Hans;q=0.7, zh-Hant;q=0.6, ja;q=0.5", @"User-Agent": @"Sally/1.0 (iPhone Simulator; iOS 7.1; Scale/2.00)" });

I am using Specta + Expecta to write the tests and my test looks like the following:

    beforeAll(^{
        [Expecta setAsynchronousTestTimeout: 5];
        [[LSNocilla sharedInstance] start];
    });
    afterEach(^{
        [[LSNocilla sharedInstance] clearStubs];
    });

    afterAll(^{
        [[LSNocilla sharedInstance] stop];
    });

    describe(@"Sign-in", ^{
        context(@"success", ^{
            it(@"should pass the token to the delegate", ^{
                stubRequest(@"GET", @"http://sally-api.dev/api/users/sign_in").
                withHeader(@"Accept", @"application/json").
                withBody(@"{\"email\":\"[email protected]\", \"password\":\"secret\"}").
                andReturn(200).
                withBody(@"api_token");

                [communicator signInWithEmail: @"[email protected]" password: @"secret"];

                expect(communicatorDelegate.apiToken).will.equal(@"api_token");
            });
        });
});

The will keyword will wait for 5 seconds until the request completes.

I'm probably missing something obvious so any help is greatly appreciated.

Testing is not a thing in the iOS and Mac community and that sucks.

Nocilla is a testing tool. There is not enough testing in our community.

It's a shame, but automated testing is not a common practice in our community. On some other platforms testing is a given, but for some reason quality is not something we as a community seem to value in our apps, libraries or open source projects.

The present

The present state of our community is quite disappointing in terms of quality and best practices. Even the most popular libraries and open source projects lack of any quality or testing. Leaders in our field blog refer to unit testing as "cargo cult programming" rather than promoting it for the professional development tool that it is. It's only human nature to be scared of the unknown, but unit testing has been a widely accepted practice for years.

What can you do?

If you really want to discuss whether you should write tests or not, or what are the benefits of unit testing, please go back in time ten years. If you want to be a professional developer and write clean code that someone else can understand, use, and modify, unit testing is definitely a tool that will help you.

You can start by writing your first test. Just one. We have the tools as well as a few people in our community that actually care enough to spend their time developing those tools and sharing their knowledge for you and me.

  • Use Kiwi. There are other testing frameworks, this one is my favorite. Thanks Allen.
  • Read Jon Reid's blog qualitycoding.org with a lot of great material including screencasts. Thanks Jon.
  • There is plenty of good material out there, including some on why we should be writing tests in the first place. Go and read the literature.

Do really want to get your hands dirty? There are many open source projects out there without any tests. I dare you to submit a pull request with one single test to the open source project of your choice. The first test is always the most difficult.

The future

Apple just announced support for continuous integration in Xcode. It's definitely good to know that Apple actually cares about testing. But again, I don't think we have a problem with tools. We have a cultural problem that we need to fix, and that's something only we (you and me) can do something about. Go and spread the word. Add test coverage to your code, it will make your life easier. Add test coverage to open source projects, you will make someone else's life easier.

I dare you to close this issue.

Can I start and stop to stub just one request ?

I have one request that want to stub and I write something like

 [[LSNocilla sharedInstance] start];

 // Do my request
  [[LSNocilla sharedInstance] clearStubs];
 [[LSNocilla sharedInstance] stop];

but subsequent request show no stub error from nocilla. Is there a way to stop it when I done using it ?

Matching request headers on iOS 8

I'm stubbing a request like the below

stubRequest(@"GET", wildUrl.regex).withHeaders(@{@"Authorization": @"Bearer 123"}).andReturn(200);

It's working fine on the iOS 7.1 sim but isn't matching the request on iOS 8 sim - it seems that the headers don't exist on the request in startLoading on LSHTTPStubURLProtocol.

Anyone else experiencing this? Stubbing is working fine on iOS 8 when not trying to match headers.

Nocilla support for NSURLSessionDataTask

I'm trying out Nocilla with AFNetworking 2.0 RC2 and it's not working. Am I missing something or does Nocilla not support NSURLSession and all the other new goodies in iOS7?

Here's an example, which does not work as I assumed it would

#import <XCTest/XCTest.h>
#import <Nocilla/Nocilla.h>
#import <AFNetworking/AFHTTPClient.h>

#define TestNeedsToWaitForBlock() __block BOOL blockFinished = NO
#define BlockFinished() blockFinished = YES
#define WaitForBlock() while (CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, true) && !blockFinished)

@interface TestNocilla : XCTestCase
@end



@implementation TestNocilla

- (void)setUp
{
    [super setUp];
    [[LSNocilla sharedInstance] start];

}

- (void)tearDown
{
    [[LSNocilla sharedInstance] stop];
    [super tearDown];
}


- (void)testB
{
    stubRequest(@"GET", @"http://www.google.com/nonsense/path");

    TestNeedsToWaitForBlock();

    AFHTTPClient *client = [[AFHTTPClient alloc] initWithBaseURL:[NSURL URLWithString:@"http://www.google.com"]];
    NSMutableURLRequest *request = [client requestWithMethod:@"GET" URLString:@"/nonsense/path" parameters:nil];

    NSURLSessionDataTask *task = [client dataTaskWithRequest:request success:^(NSURLResponse *response, id responseObject) {
        NSLog(@"success: %@", response);
        BlockFinished();
    } failure:^(NSError *error) {
        NSLog(@"fail: %@", error);
        BlockFinished();
        XCTFail(@"If Nocilla managed to stub the http call, this should not have happened");
    }];

    [task resume];
    WaitForBlock();

}

@end

Sporadic results (XCTest) when running simultaneous tests

Using Xcode 6.1, Swift, XCTest, I've got Nocilla working nicely when tests are run individually. As soon as I try to run multiple tests that use Nocilla stubs, they tests that previously succeeded on their own won't work.

For example, the following test works well on its own:

func testUserLoginFailure404() {
        let expectation = expectationWithDescription("Login Failure")
        let testEmail = "[email protected]"
        let testPassword = "loginFailure"
        let testToken = "loginFailureToken"
        let loginURLString = BRServer.baseURLString + BRServer.Login(["email":testEmail, "password": testPassword]).fullURL.path! + "/"

        stubRequest("POST", loginURLString)
            .withBody("password=\(testPassword)&grant_type=password&username=\(testEmail)")
            .andReturn(404)
            .withBody("{}")

        BRSession.createSessionFromLogin((email: testEmail, password:testPassword), success: { (token) -> Void in
            XCTFail("Login should not have succeeded")
            expectation.fulfill()
        }) { (statusCode, response) -> Void in
                XCTAssert(statusCode == 404, "should 404")
                expectation.fulfill()
        }

        waitForExpectationsWithTimeout(10.0, handler: nil)
}

However, when run alongside other session tests in the same format, the expectation will sporadically never be met (success/fail blocks aren't executed).

I've made sure that I'm using a separate request URL for each test, so that stubs don't interfere with each other in that way. Any ideas as to why it's not working?

Note: Here's what I'm doing in setUp and tearDown:

    override func setUp() {
        super.setUp()

        LSNocilla.sharedInstance().start()
    }

    override func tearDown() {
        LSNocilla.sharedInstance().clearStubs()
        super.tearDown()
    }

Thanks!

Body matcher fails to match arbitrary NSData

LSStubRequest matchesBody tries to convert the NSData body into a string which can return nil if not an actual proper string (such as gzip data).

[[NSString alloc] initWithData:reqBody encoding:NSUTF8StringEncoding]

This results in the NSData matcher failing.

Cookies vs. Nocilla

We are attempting to return a Set-Cookie header in our stubs but it seems those cookies never set. Is there some known reason why this would be the case?

When connected to our actual server we are seeing cookies set correctly, its just the stubbed responses that refuse to set them.

iOS 7 crash

Hi there,

I'm getting this error mocking an http request with Nocilla in iOS 7.1:

0x442169e: jae 0x44216ae ; __pthread_kill + 26

com.apple.NSURLConnectionLoader (9): signal SIGABRT

In iOS 8 works fine. Do you have any ideia what could be the problem?

Thanks in advance.

Ignoring headers which are not specified

What's the reason for not allowing a stub to match if you don't supply all the header info? For instance, when running tests on an iOS device, I want to stub out a request to an api which i need to supply an oauth token for. I want that token to be specified in my headers, so I do that, but I don't want to have to specify the User-Agent, as when a new version of iOS comes out, I now have to edit a bunch of tests.

What's the accepted practice here?

Add support for regular expressions

Every parameter of the stubRequest DSL should accept either a string or a regular expression.

If a string is passed a perfect match of that string with the real request.
If a regular expression is passed, that part of the real request should match the regex.

Implementation details:
The class LSStubRequest only accepts value classes (NSString, NSURL, NSData) for URL, method, body and headers. The way to go is creating a substitute class that holds matchers.

A matcher is an abstract class that is instantiated with the expected value and has a method matches: that accepts the actual value and return whether or not the actual object matches the expected one.
A family of matchers should be created for each type: LSStringMatcher, LSURLMatcher, LSDataMatcher and LSRegexMatcher. The implementation of this classes should be trivial.

Now that new LSStubRequest holds matchers, the method ´ matchesRequest:` should call every matcher with the right values and aggregate all the results.

The DSL methods should change their signature to accept id and call a factory that will introspect the type of the parameter to instantiate the right type of matcher.

Allow opt-out of exceptions for unexpected request

My app makes a good number of requests that I don't want reaching the internet (so an automatic 500 is fine) but I don't want to manually, repeatedly stub for every spec. The "hacky" 500-error actually worked well for me.

Ideally a flag could be set on the LSNocilla instance that decides how to respond to unexpected requests. I can't make the change now, but I'll fork the repo and shoot you a pull request later that does this, unless anyone has any objections.

When no headers are specified, Nocilla should match on any headers

I'm stubbing like this:

stubRequest(@"POST", @"https://example.com/foo");

And Nocilla is throwing an exception:

Terminating app due to uncaught exception 'NocillaUnexpectedRequest', reason: 'An unexcepted HTTP request was fired.

Nocilla specifies (in the console) how to properly stub the request, including the headers and body, but I'd expect it to work without having to stub the headers and body. I've verified that the URL is indeed the same, so now I'm stuck. Am I stubbing something incorrectly?

Active Achictecture Only = YES for Debug causes issue with Nocilla as a submodule

Hey, we use Nocilla for testing our product and love it. Thanks for creating this great tool! For the moment, however, we have a local mod to our Nocilla submodule to turn Active Architecture Only to off for Debug to allow us to run tests in Xcode in Debug mode in the simulator. Any chance you could change that in the next point release? Thanks!

Nocilla is not stubbing AFNetworking requests

Nocilla is not stubbing request made with AFNetworking.

The same asynchronous requests made with NSURLConnection is stubbed.
P.S: I'm using GHUnit.

This works :


    NSString *path = [[NSBundle bundleForClass:self.class] pathForResource:@"authent_ok" ofType:@"json"];
    NSData *respData = [NSData dataWithContentsOfFile:path];

    stubRequest(@"POST", @"http://youboox-recette.herokuapp.com/api/user_ipads/create_from_facebook.json").
    andReturnRawResponse(respData);

    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://youboox-recette.herokuapp.com/api/user_ipads/create_from_facebook.json"]];
    req.HTTPMethod = @"POST";

    [NSURLConnection sendAsynchronousRequest:req queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *resp, NSData *data, NSError *error) {
        NSString *respStr = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding];
    }];

This doesn't :

    NSString *path = [[NSBundle bundleForClass:self.class] pathForResource:@"authent_ok" ofType:@"json"];
    NSData *respData = [NSData dataWithContentsOfFile:path];

    stubRequest(@"POST", @"http://youboox-recette.herokuapp.com/api/user_ipads/create_from_facebook.json").
    andReturnRawResponse(respData);

    NSMutableURLRequest *req = [NSMutableURLRequest requestWithURL:[NSURL URLWithString:@"http://youboox-recette.herokuapp.com/api/user_ipads/create_from_facebook.json"]];
    req.HTTPMethod = @"POST";

    AFJSONRequestOperation *operation = [AFJSONRequestOperation JSONRequestOperationWithRequest:req success:^(NSURLRequest *request, NSHTTPURLResponse *response, id JSON) {
    } failure:^(NSURLRequest *request, NSHTTPURLResponse *response, NSError *error, id JSON) {
    }];

The request is not stubbed, i get a 403 error and i can see the call on my server logs

Error Domain=AFNetworkingErrorDomain Code=-1011 "Expected status code in (200-299), got 403" UserInfo=0xd32ef60 {NSLocalizedRecoverySuggestion=error, AFNetworkingOperationFailingURLRequestErrorKey=<NSMutableURLRequest http://youboox-recette.herokuapp.com/api/user_ipads/create_from_facebook.json>, NSErrorFailingURLKey=http://youboox-recette.herokuapp.com/api/user_ipads/create_from_facebook.json, NSLocalizedDescription=Expected status code in (200-299), got 403, AFNetworkingOperationFailingURLResponseErrorKey=<NSHTTPURLResponse: 0xb4447b0>}

Allow lenient matchers for stubRequest

Nocilla is awesome, but in the project I'm working on I'm passing a large amount of parameters in the URL (GET params). This results in a URL like this:

https://api.empanada.com/v1/burritos.json?restaurant_name=Sophies&restaurant_id=0213FC2F-5C1F-445B-964B-2B31E58EA756&restaurant_bowl_id=1

That's quite a mouthful to stub. I'd like to be able to stub any arbitrary path, without including the query params. Maybe something like this:

stubRequest(@"GET", @"https://api.empanada.com/v1/burritos.json", @{ @"restaurant_name": @"Sophies" })

The third (optional?) param could be a hash of params and values.

EXC_BAD_ACCESS in -[LSStubRequest matchesMethod:].

Issue

LSStubRequest defines method property as assign. Value for this property comes from stubRequest. Non constant string without other strong references that keep it alive used as parameter of stubRequest results in _method ivar pointing to a memory where no valid object is located.

Example

Lets say we have following configuration of Nocilla

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    [[LSNocilla sharedInstance] start];

    stubRequest(@"GET", @"http://google.com/")
        .andReturn(200)
        .withHeader(@"Content-Type", @"text/plain; charset=utf-8")
        .withBody(@"Google");

    NSString *microsoftMethod = [NSString stringWithFormat:@"%@ET", @"G"];
    stubRequest(microsoftMethod, @"http://microsoft.com/")
        .andReturn(200)
        .withHeader(@"Content-Type", @"text/plain; charset=utf-8")
        .withBody(@"Microsoft");

    return YES;
}

And a simple VC that loads 'http://google.com/' or 'http://microsoft.com/' using WebView.

@interface ViewController ()

@property (weak, nonatomic) IBOutlet UIWebView *wb;

@end

@implementation ViewController

- (IBAction)loadGoogle:(id)sender
{
    NSURL *url = [NSURL URLWithString:@"http://google.com/"];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
    [self.wb loadRequest:request];
}

- (IBAction)loadMicrosoft:(id)sender
{
    NSURL *url = [NSURL URLWithString:@"http://microsoft.com/"];
    NSURLRequest *request = [[NSURLRequest alloc] initWithURL:url];
    [self.wb loadRequest:request];
}

@end

Google stub loads as expected and Microsoft stub fails with bad access (actually any request that triggers matching process against request stub configured with shortly living 'method' string)
crash

Hook into Kiwi

When using Kiwi, in order to make Nocilla work you have to add the following snippet to every single test file. It would be great if Nocilla could hook into Kiwi to avoid this. Here is the code:

beforeAll(^{
    [[LSNocilla sharedInstance] start];
});
afterAll(^{
    [[LSNocilla sharedInstance] stop];
});
afterEach(^{
    [[LSNocilla sharedInstance] clearStubs];
});

Custom behavior when request doesn't match any expectations

Is there some way to customize the behavior of what Nocilla does when a request does not match any of the expectations set up in Nocilla? Right now Nocilla just throws an NSException, but I would really like to see it fail with a 404 error instead in certain cases.

Handle all remaining requests the same way

When I've stubbed out a request or two, the framework properly lets me know all of the rest of the requests that went through un-stubbed, and fails the test. That's a useful feature, but sometimes I know that I've stubbed what I need to test, and can safely let all other requests fail/succeed in the same fashion, regardless of their HTTP method.

Now, perhaps there usually shouldn't be other requests going on, but I have a use case where the app I'm contributing to has calls to the outside world as a part of app initialization. That's questionable practice, but I can't do anything about it here.

Here's what I'm doing now to handle that:

typedef void (^ResponseWithDoneMethod)();

@interface LSStubResponseDSL (Done)
- (ResponseWithDoneMethod)done;
@end

@implementation LSStubResponseDSL (Done)
- (ResponseWithDoneMethod)done
{
    return ^() {
        stubRequest(@"GET", @".*".regex).andReturn(400);
        stubRequest(@"POST", @".*".regex).andReturn(400);
        stubRequest(@"PUT", @".*".regex).andReturn(400);
    };
}
@end

//...

- (void)testSomething
{
    //...
    stubRequest(@"GET", @".*?/some/path".regex).
    andReturn(200).
    withBody(@"{\"key\": \"value\"}").
    done();
    //...
}

This allows me to only test the endpoint in question, and ignore everything else.

It isn't a very flexible approach, but it does what I need. Is there a way that something like this can be built in that will allow us to handle all remaining unstubbed requests in a defined way, rather than failing the current test? Maybe something like this:

- (void)testSomething
{
    //...
    stubRequest(@"GET", @".*?/some/path".regex).
    andReturn(200).
    withBody(@"{\"key\": \"value\"}").
    end().
    andReturn(400);
    //...
}

This could perhaps provide a way to take care of #2:

- (void)testSomething
{
    //...
    stubRequest(@"GET", @".*?/some/path".regex).
    andReturn(200).
    withBody(@"{\"key\": \"value\"}").
    end().
    andAllowRemaining();
    //...
}

Thoughts?

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.