Should mock objects for tests be created at a high or low level

Posted by Danack on Programmers See other posts from Programmers or by Danack
Published on 2013-10-31T01:57:46Z Indexed on 2013/10/31 4:18 UTC
Read the original article Hit count: 339

Filed under:
|

When creating unit tests for those other objects, what is the best way to create mock objects that provide data to other objects. Should they be created at a 'high level' and intercept the calls as soon as possible, or should they be done at a 'low level' and so make as much as the real code still be called?

e.g. I'm writing a test for some code that requires a NoteMapper object that allows Notes to be loaded from the DB.

class NoteMapper {

    function getNote($sqlQueryFactory, $noteID) {
        // Create an SQL query from $sqlQueryFactory
        // Run that SQL 
        // if null 
        //     return null
        // else
        //    return new Note($dataFromSQLQuery)
    }
}

I could either mock this object at a high level by creating a mock NoteMapper object, so that there are no calls to the SQL at all e.g.

class MockNoteMapper {

    function getNote($sqlQueryFactory, $noteID) {
        //$mockData = {'Test Note title', "Test note text" }
        // return new Note($mockData);
    }
}

Or I could do it at a very low level, by creating a MockSQLQueryFactory that instead of actually querying the database just provides mock data back, and passing that to the current NoteMapper object.

It seems that creating mocks at a high level would be easier in the short term, but that in the long term doing it at a low level would be more powerful and possibly allow more automation of tests e.g. by recording data in an out of a DB and then replaying that data for tests.

Is there a recommended way of creating mocks? Are there any hard and fast rules about which are better, or should they both be used where appropriate?

© Programmers or respective owner

Related posts about testing

Related posts about mocking