Frage

I would like test my class LocationMapper whose the aim is make CRUD operations:

<?php
class LocationMapper {
/*
* Database connection.
*/
var $db = NULL;


/*
* Constructor function. Loads model from database if the id is known.
*
* @param $db
*   Database connection
*/
function __construct($app) {    
    $this->db = $app['db'];
}

    /**
    * Load data from the db for an existing user.
    */
    function read($app, $id) {
    $statement = $this->db->prepare('SELECT * FROM location WHERE id = :id');
    $statement->execute(array(':id' => $id));
    $data = $statement->fetch(PDO::FETCH_ASSOC);
    $comments = $app['CommentMapper']->loadAllByLocation($id);
    $location = new Location($data['latitude'], $data['longitude'],     $data['address'], $data['name'], $data['checked'], $comments);
    $location->set('id', $data['id']);
    return $location;
   }
    ...
}

And in my index.php, I create my database connection and my mapper like this :

require_once __DIR__ . '/../config.php';

// Add the database connection as a shared service to the container.
$db_string = 'mysql:host=' . $app['db.hostname'] .';dbname=' . $app['db.dbname'];
$app['db'] = $app->share(function ($app) use ($db_string) {
   try {
      return new PDO($db_string, $app['db.username'], $app['db.password']);
   }
   catch (PDOException $e) {
      $app->abort(500, 'Unable to connect to database.  Check your configuration');
   }
});

// Initialize mappers
$app['LocationMapper'] = $app->share(function () use ($app) {
   return new LocationMapper($app);
});

How test the class LocationMapper with a real database ? I tested this :

class LocationMapperTest extends PHPUnit_Framework_TestCase
{
    protected $locationMapper;
    protected $app;

    public function setUp() {
        $app = new Silex\Application();       

        // Add the database connection as a shared service to the container.
        $db_string = 'mysql:host=' . $app['db.hostname'] .';dbname=' . $app['db.dbname'];
        $app['db'] = $app->share(function ($app) use ($db_string) {
        try {
           return new PDO($db_string, $app['db.username'], $app['db.password']);
        }
        catch (PDOException $e) {
           $app->abort(500, 'Unable to connect to database.  Check your configuration');
        }
        });
        $locationMapper = new LocationMapper();
   }

   public function createTest() {        
        $this->assertEquals(0, 0);
   }
}

but I have an error PHP Fatal error: Class 'Silex\Application' not found

War es hilfreich?

Lösung

I guess you've installed Silex using Composer, so you are including the Composer autoload at the very beginning of your application (probably inside your config.php) to automatically include all needed files. The problem is that PHPUnit is not using your config file, so it's not autoloading the classes: PHPUnit won't use an autoload file unless you told it to do so.

To tell PHPUnit to load your autoload file you have two options:

The first one is to use the bootstrap switch while executing the tests on the command line. That way, PHPUnit will include the bootstrap file at the beginning of the tests execution. If you pass it your autoload file, it will autoload your classes.

The second options is to use a configuration file, where you specify your bootstrap file.

Apart from that, a few observations about your code. Your unit tests shouldn't use your real database for testing. That way, your tests will modify the real database, making the tests unrepeteable (you'd have to re-populate the database with data if you delete rows, for example), slow, and, more importantly, you may affect real data.

I'd recommend you to mock your database, or use a database for testing purposes at least.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top