用匿名函数进行PHPUnit测试

时间:2018-09-02 06:38:05

标签: php phpunit slim anonymous-function

假设我使用的是Slim(PHP)这样的框架,并且我有一个非常现代的代码结构:

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

    // define the post actions here

});

我可以将匿名函数放入一个单独的类中,但是有没有一种方法可以在不丢失此代码结构的情况下编写测试?

谢谢。

2 个答案:

答案 0 :(得分:1)

有一些测试方法。无论如何,我建议将每个处理程序拆分到它自己的文件中(甚至可能是一个类,它具有__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
});

答案 1 :(得分:0)

如果要完全测试此匿名函数,则可以尝试模拟$app变量:

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