Skip to content

Instantly share code, notes, and snippets.

Created December 28, 2012 03:40
  • Star 0 You must be signed in to star a gist
  • Fork 2 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save anonymous/4394246 to your computer and use it in GitHub Desktop.
Make code unit-testable
<?php
// Often the case
class User {
public function getCurrentUser()
{
$user_id = $_SESSION['user_id'];
$user = App::db->select('user')->where('id', $user_id)->limit(1)->get();
if ( $user->num_results() > 0 )
{
return $user->row();
}
return FALSE;
}
}
/*
1. The above isn't testable. Command-line won't have $_SESSION available
2. Above depends on specific database implementation
*/
// First, let's abstract this out to something more generic
class User {
public function getUser($user_id)
{
$user = App::db->select('user')->where('id', $user_id)->limit(1)->get();
if ( $user->num_results() > 0 )
{
return $user->row();
}
return FALSE;
}
}
/*
The above can accept any user
*/
// Next, let's start with some basic Dependency Injection
class User {
public function __construct($db_connection)
{
$this->_db = $db_connection;
}
public function getUser($user_id)
{
$user = $this->_db->select('user')->where('id', $user_id)->limit(1)->get();
if ( $user->num_results() > 0 )
{
return $user->row();
}
return FALSE;
}
}
/*
At this point, we're basically testable. We pass in the database connection and user id, so the class
needs no knowledge of its dependencies. We can run this in a unit test and test to see if we get results.
We can switch out the database connection if we're switching from MySQL to PostgreSQL, for instance.
We can pass in any user_id, instead of only getting the "current" user.
But we can do better.
*/
// Add some further abstraction
interface iUserData {
public function getUser($user_id);
}
class MysqlUser implements iUserData {
public function getUser($user_id)
{
$user = $this->_connetion->select('user')->where('id', $user_id)->limit(1)->get();
if ( $user->num_results() > 0 )
{
return $user->row();
}
return FALSE;
}
}
class User {
public function __construct(iUserData $userdata)
{
$this->_db = $userdata;
}
public function getUser($user_id)
{
return $this->_db->getUser($user_id);
}
}
// Usage
$user = new User( new MysqlUser() );
$user_id = App::session('user_id');
$currentUser = $user->getUser($user_id);
/*
So, what just happened?
*/
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment