1

I read many post on SOF, and Google results.

Still not figure out the value of mocking.

From one of SOF' post : What is Object Mocking and when do I need it?

Object Mocking is used to keep dependencies out of your unit test. Sometimes you'll have a test like "SelectPerson" which will select a person from the database and return a Person object.

To do this, you would normally need a dependency on the database, however with object mocking you can simulate the interaction with the database with a mock framework, so it might return a dataset which looks like one returned from the database and you can then test your code to ensure that it handles translating a dataset to a person object, rather than using it to test that a connection to the database exists.

Example on above is also exist on many Google result , like this one (Code Walkthrough section) http://quickduck.com/blog/2008/02/18/unit-testing-mocking-and-dependency-injection/

But it just resulting a 100% success method for unit test assertion,because we design the mocking method & interface have to satisfy to TestCase. It can't be fail in test, it different from real world database.

Community
  • 1
  • 1
Cheung
  • 15,293
  • 19
  • 63
  • 93
  • Mocks are one way to allow testing without using the DB, the use of which would turn a test into more of an integration test. This has a few advantages, including test execution time, but also not needing a DB schema/etc at *all*, allowing development to proceed even if the DBAs are off playing skeeball. – Dave Newton Jan 05 '12 at 06:46

2 Answers2

0

Well the basic concept behind Mocking help the developer to test his code (his business logic) in isolation from other units of code or any external connections to DB, file system or services.

A code should be designed for testability and if this is achieved, then a developer know what values he will receive from the interfaces his CUT(Class Under Test) depends on. In your case, a developer should know what value will be returned from a database. He should only be concerned to check if this data (returned from the DB) is processed as per the requirement in the code he has implemented.

The condition to make all tests pass is called Over Mocking and that is caused because of lack of understanding of Test Doubles. For your particular case, if you are interested in testing the queries and not interested in testing how the returned value is processed by your application logic, then you can try using some in-memory DB like HSQLDB or H2 which are faster. In this way you can increase the scope of unit testing. But many developers would rather try to test these queries in integration testing rather than unit testing. In the actual terminology, when you use a real DB to test your code, then it is no more a unit test.

To add one more information, if you query a DB then depending on the situation you can have one or more objects or no objects returned in the result set. So you can configure your mock/stub to return one of these values. When you make the mock throw an exception like "No Results Found" then it will be a negative scenario.

Bala
  • 1,193
  • 2
  • 12
  • 34
0

Take for example this class/method:

class Foo {

    ...

    public static function instantiateFromDb(Database $db, $id) {
        $record = $db->query("SELECT * FROM table WHERE id = $id");
        $foo = new self;
        $foo->id = $record['id'];
        ...
        $foo->initialize();
        $foo->calibrate();
        return $foo;
    }

    ...

}

Foo::instantiateFromDb is a somewhat complex method that is used to instantiate an object from a database record (and yes, that's mostly pseudo code). To do this it depends on a database object, which it uses to get an entry from the database. So to test this method, you need a database with a record in it. That's quite a large dependency. You need to get the database up and running, you need a working connection to it, you need to populate the database with the right data, you need to hope that it doesn't go down. It's a dependency with lots of moving parts, when all you wanted to do is to just test the Foo::instantiateFromDb method.

So what you do is you simply mock the Database object.

public function testInstantiationFromDatabase() {
    $mockDb = new Mock('Database');

    prepare $mockDb so it always returns a valid record
    when its query() method is called...

    $this->assertInstanceOf('Foo', Foo::instantiateFromDb($mockDb, 1));
}

By mocking the database with an object that you know works (because it only does one specific thing: returning a valid record) you have taken a huge dependency out of the equation and can focus on testing only the method you actually want to test.

deceze
  • 510,633
  • 85
  • 743
  • 889