Как генерировать переменные сеанса при тестировании с phpunit

Во время тестирования фрагмента кода (написанного в соответствии с codeigniter mvc) с помощью PHPUnit я получил ошибку Неустранимая ошибка PHP: вызов функции-члена getPermissionObject () для необъектного объекта .

Код такой же, как и ниже, и его часть вызывает ошибку.

class Some_model extends Model 
{
    var $userid;
    var $permisson_object;
    var $username;
    var $userType;
    var $userFirstName;

    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();
        $this->username = $user_obj->getUsername();
        $this->userType =$user_obj->getusertype();
        $this->userFirstName = $user_obj->getFirstName()." ".$user_obj->getLastName();
    }
}

Ошибка возникла из-за того, что во время тестирования я не могу сгенерировать $ user_obj из моего тестового класса (так как он генерируется из сессии data).

Мое требование - создать то же самое в тестовом классе, чтобы я мог его использовать.

Спасибо


Спасибо за ваш ответ.

Объект выглядит примерно так:

User_library Object
(
    [username:User_library:private] => staff@some.com
    [firstname:User_library:private] => some
    [lastname:User_library:private] => Staff
    [typename:User_library:private] => 
    [userid:User_library:private] => 2
    [userType:User_library:private] => 2
    [permissionObject:User_library:private] => Permission_library Object
        (
            [create_custom_attr:Permission_library:private] => 1
            [create_jobspecific_attr:Permission_library:private] => 0
            [injob:Permission_library:private] => Array
                (
                    [products] => 2
                    [services] => 2
                    [options] => 2
                    [tasks_assigned_to_me] => 2
                    [tasks_assigned_to_others] => 2
                )

            [outjob:Permission_library:private] => Array
                (
                    [products] => 2
                    [services] => 2
                    [options] => 2
                    [tasks_assigned_to_others] => 2
                )

            [samedept:Permission_library:private] => Array
                (
                )

            [alldepts:Permission_library:private] => Array
                (
                    [add_and_assign_tasks] => 4
                    [add_and_assign_milestones] => 4
                )

        )

Я не могу найти никакой опции, чтобы смоделировать это, потому что у этого объекта также есть другие объекты. Здесь User_library Object является объектом класса User_library. Это также имеет объект Permission_library внутри него. Как я могу высмеять вышесказанное следующим образом:

$observer = $this->getMock('Some_model', array('Some_model'));

$observer->expects($this->any())
                 ->method('Some_model')
                 ->with($this->equalTo('something'));

Здесь моя проблема в том, что было бы в части что-то в $ this-> equalTo ('thing ') ?

1
задан Eborbob 22 December 2017 в 14:20
поделиться

1 ответ

Один из возможных ответов на вашу проблему - «Внедрение зависимостей» , честно говоря, тот, который мне нравится больше всего. Также возможно простое издевательство.

В некоторых примерах

<?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 . Надеюсь, эта помощь проясняет то, что я пытался объяснить :)

Edit

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 утверждения)

Я очень надеюсь, что это поможет. Это много кода, но в качестве демонстрации он должен работать на вас.

2
ответ дан 2 September 2019 в 22:06
поделиться
Другие вопросы по тегам:

Похожие вопросы: