Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How will one make an unit test in PHP if an ORM layer is used?

I have a class let's say Person. The ORM layer has generated based on the sql structure the corresponding objects. The class person has a method: Get($id). In the Get method, the object Person is called and the field from the table are retrieved.

I basically want to make the following unit test: create a new person and check if the Get method is returning the right information.

  • How is the unit testing supposed to work in this condition ?
  • Do I need to create a separate database ( just the structure ), and make the creation/selection from that database?
  • Should the boostrap file load the same configuration as the framework I'm using but change the configuration file so It works with the fake database ?
  • Should I clean the new database each after each test ?

    I was also wandering after seeing your responses if simulating an ORM response without actually building a new database is not the way to go ?

  • like image 205
    johnlemon Avatar asked Apr 05 '11 05:04

    johnlemon


    2 Answers

    How is the unit testing supposed to work in this condition ?

    Generally, you should split your unittests mentally in two parts:

    • one part of your code is testable without the database, so you can stub or mock the methods that do the database access
    • the other part of your tests needs to work with the database, since it tests if the ORM is used correctly.

    Do I need to create a separate database

    This depends on your needs. Rails apps generally have testing/development/production "environments" - database, configuration, storage directories. Testing is for running unit tests, dev for developing things and production for running the live server. While developing, you run against the dev configuration and thus your development database. For unit tests, the testing env is used which has the benefit that i.e. users in the database are not deleted or broken.

    I like that concept; in my phpunit tests I often do have a switch in the bootstrap that changes which configuration file is loaded. Just remember that your development database often contains more data than a single unit test needs, and you probably hand-crafted that data and do not want to lose. Also, another database does not cost money.

    Should I clean the new database each after each test?

    I mostly clean the tables only that will be used in the test. Cleaning your database makes sure you don't get side-effects from previous tests.

    like image 168
    cweiske Avatar answered Sep 21 '22 02:09

    cweiske


    Check out Phactory. I prefer it over the database extensions included in PHPUnit and it makes it really easy to insert records into your test db.

    require_once 'Phactory/lib/Phactory.php';
    
    Phactory::setConnection(new PDO('sqlite:test.db'));
    
    Phactory::define('user', array('name'  => 'Test User',
                                   'email' => '[email protected]'));
    
    $user = Phactory::create('user'); // creates a row in the 'users' table
    
    print("Hello, {$user->name}!"); // prints "Hello, Test User!"
    

    Your System Under Test (SUT) will need to connect to your test database. The idea is that you populate just the records you need for the method you are testing. The orm layer shouldn't matter if the test db has all the same tables and fields as your production database.

    like image 42
    james Avatar answered Sep 23 '22 02:09

    james