One possible answer to your problem is "Dependency Injection"
, frankly the one i like best. Just plain mocking is also possible.
Some expamples
<?php
// You could pass the session into the object while constructing it
// so in your test you can pass in a "fake" user object (see below)
class Some_model extends Model {
function Some_model($user_object) {
$user_object->yourFunctions();
}
this way you don't have to rely on some global state beeing set up the right way.
If that doesn't work for you ( i don't know codeigniter really well ) you could maybe to it like this:
<?php
class Some_model extends Model {
function Some_model($user_object=null) {
if($user_obj === null) {
$user_obj = @unserialize($this->db_session->userdata('user_object'));
}
$user_object->yourFunctions();
}
so in your tests you pass in a mocked user object ( a fake instance you created, for mocking see the docs) and your normal code doesn't have to change.
Also a good read: Slides about PHPUnit best practices from the PHPUnit Author. Hopefully the help clarify what i was trying to explain :)
Edit
sidhartha asked for some help with the mocking so i wrote some more demo code.
I've stripped out most things to provide a full executable example as i guess "code you can run" is more helpful then anything else.
Let's say this is the code you want to test (reduced to the userid so it's shorter)
<?php
class Some_model extends Model
{
var $userid;
var $permisson_object;
function Some_model()
{
parent::Model();
$user_obj = @unserialize($this->db_session->userdata('user_object'));
//following line shows error
$this->permisson_object = $user_obj->getPermissionObject();
$this->userid = $user_obj->getUserid();
}
}
Working with what i have tried to explain you could build a test like this one (everything in one file to make copy paste eaiser, of course one would split it)
class Model { public function Model() {} }
class Some_model extends Model
{
var $userid;
var $permisson_object;
function Some_model($user_obj)
{
parent::Model();
//following line shows error
$this->userid = $user_obj->getUserid();
$this->permisson_object = $user_obj->getPermissionObject();
}
public function getThatUserid() {
// Just to show off how mocking works a little bit better :)
return $this->userid;
}
}
class Permissions {
public function getPermissions() {
// lots of code here maybe
return array("something from" => "the database");
}
}
class User {
public function getUserid() {
// code code
return 1;
}
public function getPermissionObject() {
}
}
class Some_modelTest extends PHPUnit_Framework_Testcase {
public function testConstruction() {
$mockUser = $this->getMock("User");
$mockPermissions = $this->getMock("Permission");
$mockUser->expects($this->once())
->method("getUserid")
->will($this->returnValue(100));
# $mockPermissions->expects($this->once())
# ->method("getPermissions");
// Now for the "magic"
$mockUser->expects($this->once())
->method("getPermissionObject")
->will($this->returnValue($mockPermissions));
// ^^ now we are all set and user_obj is independen of the permissons object
// Now pass the "Fake" user into the model
$model = new Some_model($mockUser);
// and just to show off the "will return value stuff"
$this->assertSame(100, $model->getThatUserid());
}
}
phpunit Some_modelTest.php PHPUnit
3.4.15 by Sebastian Bergmann.
.
Time: 0 seconds, Memory: 4.25Mb
OK (1 test, 3 assertions)
I really hope that helps. It's a lot of code but as a demo it should work for you.