2

I am trying to get familar with the Kiwi BDD testing framework. I am using it it in conjuction with Nocilla to mock HTTP requests. Both projects look awesome but I am having some difficulty with it. I have the following test spec:

    beforeAll(^{ // Occurs once
         [[LSNocilla sharedInstance] start];
    });

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

    beforeEach(^{ // Occurs before each enclosed "it"
        couch = [[Couch alloc]initWithDatabaseUrl:@"http://myhost/mydatabase"];
    });

    afterEach(^{ // Occurs after each enclosed "it"
        [[LSNocilla sharedInstance] clearStubs];
    });

    it(@"should be initialized", ^{
        [couch shouldNotBeNil];
    });

    context(@"GET requests", ^{
    it(@"should get document by id", ^{
        __block NSData *successJson = nil;
        __block NSError *requestErr = nil;
        stubRequest(@"GET", @"http://myhost/mydatabase/test").
        withHeader(@"Accept", @"application/json").
        withBody(@"{\"_id\":\"test\",\"_rev\":\"2-77f66380e1670f1876f15ebd66f4e322\",\"name\":\"nick\"");

        [couch getDocumentById:@"test" success:^(NSData *json){
            successJson = json;
        } failure:^(NSError *error) {
            requestErr = error;
        }];

        [[successJson shouldNot]equal:nil];

    });
    });

Sorry for the long code snippet. I want to make sure I give context. As you can see I am testing the behavior of an object which makes a GET request and reports the results in a 'success' block and reports errors in a 'failure' block. I have two __block vars to store success and failures receptively. Currently the test checks that the 'success' var has a value (not nil). This test passes. However debugging this test it appears neither blocks are ever executed. The successJson appears nil. I would expect Nocilla to have passed the stub body content to the success block parameter. So is my test constructed incorrectly?

Thanks!

Nick
  • 19,198
  • 51
  • 185
  • 312

1 Answers1

4

The general structure of your test looks OK. For asynchronous testing, use this:

[[expectFutureValue(theValue(successJson != nil)) shouldEventually] beTrue];

The reason for the != nil and beTrue above is that there is no shouldEventually + notBeNil sort of combination that you can use to test for an eventual nil value. The test above will find that successJson is initially nil, and thus will continue to poll that value until your callback makes it non-nil.

Note that if you were doing a positive test, such as checking for successJson == @"test", then you could use a simpler form for the expectation:

[[expectFutureValue(successJson) shouldEventually] equal:@"test"];

Also note that you can use shouldEventuallyBeforeTimingOutAfter(2.0) to increase the default timeout (1 second I think) to whatever timeout you want for asynchronous expectations.

Mike Mertsock
  • 11,825
  • 7
  • 42
  • 75