假设我使用的是Slim(PHP)这样的框架,并且我有一个非常现代的代码结构:
$app->post("/", function($request, $response) {
// define the post actions here
});
我可以将匿名函数放入一个单独的类中,但是有没有一种方法可以在不丢失此代码结构的情况下编写测试?
谢谢。
答案 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
});