Since the last blog post, quite some nice things happened: I moved to a new house, we released LibreOffice 4.0.0 fantastic release and Markus helped me write better unit tests for libcmis.In this post, I’ld like to give some details on these new unit tests. To understand the need of changing unit tests, you need to know that libcmis test script was downloading, setting up and starting an Apache Chemistry InMemory server to interact with. This system had several drawbacks like slow unit tests and dependency on the test server features and bugs for inventing new test cases. To work this around, Markus helped me to setup a libcurl mockup library.

The principle is pretty simple: replace the normal libcurl used to send the HTTP requests to the server by a mockup library. The mockup can then store the sent requests and provide the responses we want (either valid ones or invalid ones). The code of the mockup is still evolving and can be found in the qa/mockup folder of libcmis source tree. One of the key functions to get it working is curl_mockup_addResponse: it tells the mockup what response to provide under which circumstances. This function may still need some more parameters to cover all cases, but it will associate a response (body, headers, status) with a request (URL, HTTP method). The other important function for testing is curl_mockup_getRequest: it gives back the request content for a URL and HTTP method. It helps making sure that our code sent the proper request.

As always, a small code snippet helps a lot to understand. Let’s take one derived from libcmis unit tests.

void AtomTest::createDocumentTest( )
{
    // Reset the mockup configuration to avoid keeping other tests config
    curl_mockup_reset( );

    // Add a response to match. In this case, a POST request with a URL like
    // http://mockup/mock/children?id=root-folder&somethingelse will fit
    // The response will have:
    //    - the body: "Response body up to server"
    //    - the HTTP status: 201
    //    - the HTTP Headers with Location defined
    curl_mockup_addResponse( "http://mockup/mock/children", "id=root-folder", "POST",
                             "Response body up to server", 201, false,
                             "Location: http://mockup/mock/id?id=create-document\r\n" );

    // Set the authentication credentials needed to fake the server
    curl_mockup_setCredentials( SERVER_USERNAME, SERVER_PASSWORD );

    // Create the CURL handle (in the session for libcmis)
    AtomPubSession session = getTestSession( SERVER_USERNAME, SERVER_PASSWORD );

    // Do something with the CURL handle (the session for libcmis)
    ...

    // You can check that your code worked fine (thanks to the response you provided)
    ...

    // You can also check that the request was the expected one
    // or matched some important criteria (beware of timestamps
    // and variable bits in the requests)
    string request( curl_mockup_getRequest( "http://mockup/mock/children",
                                                                "id=root-folder", "POST" ) );
    CPPUNIT_ASSERT_EQUAL_MESSAGE( "Wrong request  sent", expectedRequest, request );
}

I hope this testing experience can help others testing their HTTP client application based on libcurl. Of course, something similar can be done with other HTTP client libraries.