PHPUnit: тестовый массив объектов



Только недавно заскочил в PHPUnit, читал о нем, пробовал некоторые примеры, чтобы освоиться в написании тестов для моих будущих проектов.



Мне нужно проверить этот сценарий, у меня есть класс студентов, который выглядит так:



class Students
{
public function getStudents($studentName, $studentId)
{
$students= array();

//Instantiating OldStudent Class from Old Project
$oldStudents = OldStudents::getStudentByName($studentName, $studentId);

//Create a Student Object for every OldStudent found on Old Project and set
//values
foreach ($oldStudents as $oldStudent)
{
$student = new EntityStudent();

//Set Student ID
$student->setStudentId($oldStudent->getStudentID());

//Set Student Name
$student->setStudentName($oldStudent->getStudentName());
//.....other setters for student data, irrelevant for this example

$students[] = $student;
}

return $students;
}
}


И класс учащихся



Class Student
{
protected $studentId;
protected $studentName;

public function getStudentId()
{
return $this->studentId;
}
public function setStudentId($studentId)
{
$this->studentId = $studentId;
return $this;
}
public function getStudentName()
{
return $this->studentName;
}
public function setStudentName($studentName)
{
$this->studentName = $studentName;
return $this;
}
}


Теперь как я могу проверить, возвращает ли класс Students массив объектов с заданными значениями и проверить значения с помощью геттеров из Student Класс



Пожалуйста, бросьте немного света / информации / ссылок, которые укажут мне правильный путь.



Спасибо

652   3  

3 ответов:

Ниже я написал пример кода; я предположил, что параметры для getStudents были необязательными фильтрами. У нас есть один тест, который получает все студенты. Я не знаю, всегда ли они возвращаются в упорядоченном порядке, поэтому я больше ничего не тестирую в студенческом классе. Второй тест получает одного конкретного студента и начинает проверять некоторые свойства студента.

class StudentsTest extends PHPUnit_Framework_TestCase{

    public function testGetAllStudents(){
        $s=new Students;
        $students=$s->getStudents("","");
        $this->assertInternalType('array',$students);
        $this->assertEquals(7,count($students));
        $first=$students[0];    //Previous assert tells us this is safe
        $this->assertInstanceOf('Student',$first);
    }

    public function testGetOnlyStudentNamedBob(){
        $s=new Students;
        $students=$s->getStudents("Bob","");
        $this->assertInternalType('array',$students);
        $this->assertEquals(1,count($students));
        $first=$students[0];    //Previous assert tells us this is safe
        $this->assertInstanceOf('Student',$first);
        $this->assertEquals('Bob',$first->getStudentName());
    }
}

Это хороший первый шаг. После того, как вы используете его в течение некоторого времени, вы поймете, что он довольно хрупкий. То есть у вас должно быть ровно 7 студенты для первого теста, чтобы пройти. Там должен быть ровно один студент по имени Боб, чтобы второй прошел. Если ваш \OldStudents::getStudentByName получает данные из базы данных, он также будет медленным; мы хотим, чтобы модульные тесты выполнялись как можно быстрее.

Исправление для обоих из них состоит в том, чтобы издеваться над вызовом \OldStudents::getStudentByName. Затем вы можете ввести свои собственные искусственные данные, и тогда вы будете только проверять логику в getAllStudents. Что в свою очередь означает, что когда ваш модульный тест ломается, есть только 20 или около того строк, где вы могли бы сломаться он, не 1000е.

Точно, как сделать насмешку, - это целый вопрос, который может зависеть от версии PHP и от того, насколько гибка ваша настройка кода. ("Олдстуденты" звучит так, как будто вы имеете дело с устаревшим кодом, и, возможно, вы не можете коснуться его.)

PHPUnit начиная с версии 3.1.4 имеет утверждение " assertContainsOnly "с параметром" type", который может утверждать любой тип PHP (включая экземпляры и внутренние типы), и по крайней мере в версии 3.7 имеет утверждение" assertContainsOnlyInstancesOf", которое явно проверяет только экземпляры классов, а не типы переменных PHP.

Поэтому тест, проверяющий, содержит ли массив только объекты данного типа, прост:

$this->assertContainsOnlyInstancesOf('Student', $students);

Обратите внимание, что эта проверка неявно проверяет, что $students является либо массив или объект, реализующий проходимый интерфейс. Реализация Traversable не означает, что вы можете считать, поэтому вызов assertCount после утверждения заданного числа объектов Student не гарантирует успеха, но добавленная проверка того, что возвращаемое значение на самом деле является массивом, кажется мне здесь слишком раздутой. Вы создаете и возвращаете массив с чем - то в нем-можно с уверенностью предположить, что вы можете его пересчитать. Но это может быть не везде так.

Вы можете сделать это с утверждениями. Прежде всего вы должны получить фактический результат, а затем сделать с ним несколько утверждений. Сравните:

Можно утверждать, что это массив:

class InternalTypeTest extends PHPUnit_Framework_TestCase
{
    public function testFailure()
    {
        $this->assertInternalType('array', 42);
    }
}

Тогда вы можете утверждать, что он не пуст (так как вы знаете, что он должен возвращать некоторые данные):

class NotEmptyTest extends PHPUnit_Framework_TestCase
{
    public function testFailure()
    {
        $this->assertNotEmpty(ARRAY());
    }
}

И затем вы можете утверждать, что каждое значение принадлежит вашему типу ученика:

class InstanceOfTest extends PHPUnit_Framework_TestCase
{
    public function testFailure()
    {
        $this->assertInstanceOf('Student', new Exception);
    }
}

Я надеюсь, что это даст вам некоторые указатели. Список распространенных утверждений см. по ссылке выше. Если вы используете IDE для записи теста, он также должен предлагать список всех утверждений.

Comments

    Ничего не найдено.