Один из возможных ответов на вашу проблему - "Dependency Injection"
, честно говоря, тот, который мне нравится больше всего. Также возможно простое издевательство.
Некоторые образцы
<?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();
}
таким образом, вам не нужно полагаться на то, что какое-то глобальное состояние настроено правильно.
Если это не сработает для вас (я не очень хорошо знаю codeigniter), вы можете сделать это примерно так:
<?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();
}
поэтому в своих тестах вы передаете имитированный пользовательский объект (созданный вами поддельный экземпляр, для см. Документацию ) и ваш обычный код не должен изменяться.
Также хорошая статья: Слайды о лучших практиках PHPUnit от автора PHPUnit . Надеюсь, помощь уточнить, что я пытался объяснить:)
Редактировать
sidhartha попросил помощи с насмешкой, поэтому я написал еще несколько демонстрационных кодов.
Я упустил большинство вещей, чтобы предоставить полный исполняемый пример, так как «код, который вы можете запустить» более полезен, чем что-либо другое.
Допустим, это код, который вы хотите протестировать (сокращен до идентификатора пользователя, поэтому он короче)
<?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();
}
}
Работая с тем, что я пытался объяснить, вы могли бы создать такой тест (все в одном файле, чтобы сделать копию-вставку eaiser, конечно, можно было бы разбить его)
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 Себастьян Бергманн.
.
Время: 0 секунд, память: 4,25 МБ
ОК (1 тест, 3 утверждения)
Я действительно надеюсь, что это поможет. Это много кода, но в качестве демонстрации он должен работать для вас.