Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/240.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 您将如何测试这种典型的控制器方法?_Php_Unit Testing_Model View Controller_Phpunit - Fatal编程技术网

Php 您将如何测试这种典型的控制器方法?

Php 您将如何测试这种典型的控制器方法?,php,unit-testing,model-view-controller,phpunit,Php,Unit Testing,Model View Controller,Phpunit,我正在使用PHPUnit测试我的MVC应用程序。我的模型的大部分代码(本例中的Site、MStudent、MMenu)都包含了单元测试,但我发现很难在控制器上测试功能。我的框架中的典型控制器功能如下所示: /** * List the mentor's students */ public function students() { // set some variables needed in the view $menu = MMenu::init($this->m

我正在使用PHPUnit测试我的MVC应用程序。我的模型的大部分代码(本例中的Site、MStudent、MMenu)都包含了单元测试,但我发现很难在控制器上测试功能。我的框架中的典型控制器功能如下所示:

/**
 * List the mentor's students
 */
public function students()
{
    // set some variables needed in the view
    $menu = MMenu::init($this->mentor, "List of students");
    $filter = "";
    $students = array();

    $sql = "SELECT * "
            . "FROM {Site::app()->settings['tablePrefix']}students s "
            . "WHERE s.pID = {$this->mentor->id} "
            . "ORDER BY s.lastvisit DESC";

    $cmd = Site::app()->db()->prepare($sql);
    if ($cmd->execute() AND ($rows = $cmd->fetchAll(PDO::FETCH_ASSOC)))
    {
        foreach ($rows as $row)
        {
            $students[] = new MStudent($row);
        }
    }

    // call the view
    include Site::app()->viewPath("manage/students");
    exit;
}
里面有什么可以测试的东西吗?你将如何测试它

编辑:
因此,根据Stephen的反馈,我可以重构并将数据库访问放在模型中:

public function students()
{
    // set some variables needed in the view
    $menu = MMenu::init($this->mentor, "List of students");
    $filter = "";

    $students = MStudent::studentsFromQuery("SELECT * FROM students WHERE pID=" . $this->mentor->id);

    // call the view
    include Site::app()->viewPath("manage/students");
    exit;
}

现在这里要测试的东西更少了。测试这样的功能有意义吗?如何做?

应该注意,将控制器逻辑移动到模型中并不排除在控制器测试中测试它的需要!你进入模型的任何东西都会被嘲笑


很少有一个控制器能够以一种值得的方式进行单元测试(IMO)。模拟所有依赖项的成本/收益并没有得到回报。通常,控制器方法会作为系统测试的一部分进行间接测试。

如果这是MVC,那么我认为您的控制器有点胖。确定数据库访问应该在模型中吗?是的,数据库查询肯定应该在模型中。我会将整个查询放入模型中,以从控制器中抽象出所有SQL。在
MStudent
上创建一个方法,例如
studentsformontor($menterid)
。此外,使用静态方法测试代码也会很困难。调用
exit
也是测试的杀手。至少把它放在基本控制器中的
doExit()
方法中,您可以在测试期间模拟或禁用它。看来SO社区中没有人有更好的答案,所以我接受您的方法。谢谢你的回答。它澄清了困扰我很久的一些事情。