使用匿名函数进行PHPUnit测试

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了使用匿名函数进行PHPUnit测试相关的知识,希望对你有一定的参考价值。

假设我使用像Slim(php)这样的框架,我有这个相当现代的代码结构:

$app->post("/", function($request, $response) {

    // define the post actions here

});

我可以将匿名函数放入一个单独的类中,但有没有办法编写测试而不会丢失这个代码结构?

谢谢。

答案

有一些方法可以测试它。无论如何,我建议将每个处理程序拆分为它自己的文件(可能甚至是一个具有__invoke方法的类)。原因是这种定义处理程序的方式现在看起来简短而清晰。但是一旦你有超过10个端点,它就会变得非常难以维护,并且你将路由逻辑与不同的处理程序混合在一起。

如果这是一个非常小的项目,并且您希望保留这种语法,则有两种策略可以对其进行测试。但请注意,它们都比您想要的更麻烦:

集成测试样式(不推荐)

你只需在测试中调用$slim->run()并检查处理程序的输出是否符合你的期望。 Slim提供了一种模拟http请求as you can find at the bottom of that page的好方法。请注意,您将仅限于检查从处理程序返回的数据。如果处理程序返回纯html,则只能检查返回的html是否包含正确的内容。

如果您使用slim的依赖注入功能并为其提供模拟,您可以更进一步。

简单的处理程序样式(推荐)

或者,您也可以在路由中保留匿名处理函数,但是将实际业务逻辑的处理推迟到另一个类,然后您可以测试该类。如果您的控制器非常简单,除了检索GET / POST参数并将它们转发到类之外什么都不做,那么就没有那么多测试了。

除了这给你一个测试的角度,它也是一个更好的方式来考虑关注的分离。你的超薄处理程序函数将处理框架和HTTP基础知识,你将有一个很好的域类,不需要打扰它。

$app->post("/register", function() {
    $result = (new RegisterUserAction())
        ->register($_POST["email"], $_POST["password1"], $_POST["password2"]); 
    // now use $result to render the html page to show to the user
});
另一答案

如果你想测试这个匿名函数,你可以尝试模拟一个$app变量:

$app = $this->getMockBuilder('app class')->disableOriginalConstructor()
    ->setMethods(['post'])
    ->getMock();
$app->method('post')->willReturnCallback(function ($url, $anonymousFunction) {
    // do some tests with $anonymousFunction
});

以上是关于使用匿名函数进行PHPUnit测试的主要内容,如果未能解决你的问题,请参考以下文章

如何使用返回 IP 的函数进行 PHPUnit 测试?

Laravel 和 phpunit - 无法进行测试

使用 PHPUnit 对具有多种用户类型的网站进行单元测试的最佳方法

PHPUnit - 使用 $_POST 变量测试 MVC 控制器

catch 块内的 PHPUnit 测试代码

PHPUnit 单元测试