views:

44

answers:

2

I'm trying to write some tests with PHPUnit for our various classes/methods/functions. Some of these require database connectivity. Obviously, I'd like to Mock these, so that I don't change our database(s).

Can someone point me to some code that explains how to do this? I see lots of examples of Mocking, but nothing specifically about mocking the database.

+2  A: 

In general, you don't want to mock the database, or any other similar external dependency. It's better to wrap the database in your code with something else, and then you can mock the wrapper. Because a database might have many different ways that it can interact, whereas your code and your tests only care about one or two, your database wrapper only needs to implement those. That way mocking the wrapper should be quite simple. You would also need some kind of integration test on the wrapper to check it's doing what it's supposed to, but there will only be a few of these tests so they won't slow your unit tests too much.

Jonny Cundall
I guess "mocking the database" is the wrong term. We use ezSQL in-house, and I want to mock around it, so that I can test everything else...
gms8994
A: 

Mock of Database

I would write a wrapper around the calls to the Database in the application.
Example in Pseudo Code

CallDataBase (action, options,...) {
    // Code for connectiong to DataBase
}

Then you just mock of that function just you would like any other function

CallDataBase (action, options,...) {
    return true;
}

This way you can mock of the database without bothering about it being a webservice or a database connection or whatever. And you can have it return true or whatever.

Test how your system handles the database response

To take this idea one step further and make your tests even more powerful you could use some kind of test parameters or environment parameters to control what happens in the mocked off database method. Then you can successfully test how your codes handels different responses from the database.
Again in pseudo-code (assuming your database returns xml answer):

CallDataBase (action, options,...) {
    if TEST_DATABASE_PARAMETER == CORRUPT_XML
        return "<xml><</xmy>";
    else if TEST_DATABASE_PARAMETER == TIME_OUT
        return wait(5000);
    else if TEST_DATABASE_PARAMETER == EMPTY_XML
        return "";
    else if TEST_DATABASE_PARAMETER == REALLY_LONG_XML_RESPONSE
        return generate_xml_response(1000000);
}

And tests to match:

should_raise_error_on_empty_xml_response_from_database() {
    TEST_DATABASE_PARAMETER = EMPTY_XML;
    CallDataBase(action, option, ...);
    assert_error_was_raised(EMPTY_DB_RESPONSE);
    assert_written_in_log(EMPTY_DB_RESPONSE_LOG_MESSAGE);
}
...

And so on, you get the point. Please note that all my examples are Negative test cases but this could of course be used to test Positive test cases also.

Good Luck

Jonas Söderström