Royall Spence's Blog

Making CodeIgniter Models Testable With PHPUnit

When you find yourself with an old CodeIgniter application, it’s natural to want to ditch the framework. You want something more up-to-date to work with, but you need the application behaviors to remain intact. The first thing to do is mop up the mess of legacy code. When it’s time to change a feature or investigate a bug, get the relevant section under test first. In my case, the problem involved a model class. This was a very “fat” model with lots of logic inside of it. A typical CI model doesn’t show much hope on its own. It calls a superclass constructor that sets the database connection and everything else automatically. This example model from the documentation provides a classic case:

 class Blogmodel extends CI_Model {

    var $title   = '';
    var $content = '';
    var $date    = '';

    function __construct()
    {
        // Call the Model constructor
        parent::__construct();
    }
    
    function get_last_ten_entries()
    {
        $query = $this->db->get('entries', 10);
        return $query->result();
    }

The good news is we aren’t stuck in this situation. With a little change to the constructor, we can inject a fake or mock database connection. This will allow us to run each method in the class while our tests supply the database results we desire. Adapting the model constructor is pretty straightforward:

    function __construct($db = false)
    {
        // Call the Model constructor
        parent::__construct();
        
        if($db !== false){
            $this->db = $db;
        }
    }