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

发布于 2024-11-27 20:49:55 字数 1412 浏览 1 评论 0原文

我正在使用 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;
}

那里有值得测试的东西吗?你会如何测试它?

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

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;
}

现在这里需要测试的东西更少了。测试这样的功能是否有意义以及如何做到这一点?

I'm using PHPUnit to test my MVC application. Most of the code for my models (Site, MStudent, MMenu in this example) are well covered with unit tests, but I find it difficult to test the functions on my controllers. A typical controller function in my framework looks like this:

/**
 * 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;
}

Is there something senseable to test in there? How would you test it?

EDIT:
So from Stephen's feedback, I can refactor and put the database access in the model:

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;
}

Now there is even less to test here. Does it make sense to test functions like these and how would one do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

千柳 2024-12-04 20:49:55

应该注意的是,将控制器逻辑移至模型中并不排除在控制器测试中对其进行测试的需要!无论你进入模型的是什么,都必须被嘲笑。

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

It should be noted that moving controller logic into the models does not preclude the need to test it in your controller tests! Whatever you move into the models will have to be mocked.

It's rare to have a controller that does so little that it can actually be unit tested in a way that makes it worthwhile (IMO). The cost/benefit to mocking all of the dependencies just doesn't pay off. Often controller methods are instead tested indirectly as part of system tests.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文