单元测试

编辑本页

单元测试

你可能已经注意到我们在前一章中构建的框架中有一些微妙但重要的错误。在创建框架时,必须确保它的行为与所宣传的一致。否则,所有基于它的应用程序都将出现相同的错误。好消息是,无论何时欧宝平台是合法的吗您修复了一个错误,您都在修复一堆应用程序。

今天的任务是为我们创建的框架编写单元测试PHPUnit).首先,将PHPUnit作为开发依赖项安装:

1
编译器需要——dev phpunit/phpunit

然后,在中创建PHPUnit配置文件example.com/phpunit.xml.dist

12 3 4 5 6 7 8 9 10 11 12 13 14 16 17 18 19 20
<?xml version="1.0" encoding="UTF-8"?><phpunit)xmlns: xsi“http://www.w3.org/2001/XMLSchema-instance”xsi: noNamespaceSchemaLocation“https://schema.phpunit.de/9.3/phpunit.xsd”backupGlobals“假”颜色“真正的”引导“供应商/ autoload.php”><报道processUncoveredFiles“真正的”><包括><目录后缀“。php”>. / src目录>包括>报道><testsuite文件><testsuite的名字“测试套件”><目录>。/测试目录>testsuite>testsuite文件>phpunit)>

这个配置为大多数PHPUnit设置定义了合理的默认值;更有趣的是,自动加载器用于引导测试,并且测试将存储在example.com/tests/目录中。

现在,让我们为“未找到”资源编写一个测试。为了避免在编写测试时创建所有依赖项,并真正地只对我们想要的进行单元测试,我们将使用测试双打.当我们依赖于接口而不是具体类时,更容易创建测试双精度对象。幸运的是,Symfony为ob娱乐下载URL匹配程序和控制器解析器等核心对象提供了这样的接口。修改框架以使用它们:

12 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/ / example.com/src/Simplex/Framework.php名称空间单纯形/ /……使用日历控制器LeapYearController使用ob娱乐下载组件HttpKernel控制器ArgumentResolverInterface使用ob娱乐下载组件HttpKernel控制器ControllerResolverInterface使用ob娱乐下载组件路由匹配器UrlMatcherInterface框架受保护的匹配器受保护的controllerResolver受保护的argumentResolver公共函数__construct(UrlMatcherInterface匹配器, ControllerResolverInterface解析器, ArgumentResolverInterfaceargumentResolver->匹配器=匹配器->controllerResolver =解析器->argumentResolver =argumentResolver;}/ /……

现在我们准备编写第一个测试:

12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
/ / example.com/tests/Simplex/Tests/FrameworkTest.php名称空间单纯形测试使用PHPUnit)框架TestCase使用单纯形框架使用ob娱乐下载组件HttpFoundation请求使用ob娱乐下载组件HttpKernel控制器ArgumentResolverInterface使用ob娱乐下载组件HttpKernel控制器ControllerResolverInterface使用ob娱乐下载组件路由使用ob娱乐下载组件路由异常ResourceNotFoundExceptionFrameworkTest扩展TestCase公共函数testNotFoundHandling()框架->getFrameworkForException (ResourceNotFoundException ());响应框架->处理(请求());->assertequal (404响应->getStatusCode ());}私人函数getFrameworkForException异常匹配器->createMock(路由\匹配器\ UrlMatcherInterface::类);//在PHPUnit 5.3或以下使用getMock(// $matcher = $this->getMock(Routing\ matcher \UrlMatcherInterface::class);匹配器->预计(->一旦())->方法(“匹配”->将(->throwException (异常));匹配器->预计(->一旦())->方法(“getContext”->将(->returnValue (->createMock(路由\ RequestContext::类)));controllerResolver->createMock (ControllerResolverInterface::类);argumentResolver->createMock (ArgumentResolverInterface::类);返回框架(匹配器controllerResolverargumentResolver);}}

此测试模拟不匹配任何路由的请求。因此,匹配()方法返回ResourceNotFoundException异常,我们正在测试我们的框架将这个异常转换为404响应。

通过运行执行此测试phpunit)example.com目录:

1
/供应商/ bin / phpunit)

请注意

如果您不明白代码中到底发生了什么,请阅读PHPUnit文档欧宝官网下载app测试双打

在测试运行之后,您应该看到一个绿色的条。如果不是,那么您在测试或框架代码中有bug !

为控制器中抛出的任何异常添加单元测试:

1 2 3 4 5 6 7 8
公共函数testErrorHandling()框架->getFrameworkForException (\ RuntimeException ());响应框架->处理(请求());->assertequal (500响应->getStatusCode ());}

最后,但并非最不重要的,让我们写一个测试,当我们实际上有一个适当的响应:

12 34 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
使用ob娱乐下载组件HttpFoundation响应使用ob娱乐下载组件HttpKernel控制器ArgumentResolver使用ob娱乐下载组件HttpKernel控制器ControllerResolver/ /……公共函数testControllerResponse()匹配器->createMock(路由\匹配器\ UrlMatcherInterface::类);//在PHPUnit 5.3或以下使用getMock(// $matcher = $this->getMock(Routing\ matcher \UrlMatcherInterface::class);匹配器->预计(->一旦())->方法(“匹配”->将(->returnValue ([“_route”= >“is_leap_year /{一}”“年”= >“2000”“_controller”= > [LeapYearController (),“指数”],]);匹配器->预计(->一旦())->方法(“getContext”->将(->returnValue (->createMock(路由\ RequestContext::类)));controllerResolverControllerResolver ();argumentResolverArgumentResolver ();框架框架(匹配器controllerResolverargumentResolver);响应框架->处理(请求());->assertequal (200响应->getStatusCode ());->assertStringContainsString (“是的,今年是闰年!”响应->getContent ());}

在这个测试中,我们模拟了一个匹配并返回一个简单控制器的路由。我们检查响应状态是否为200,其内容是否为我们在控制器中设置的内容。

为了检查我们已经覆盖了所有可能的用例,运行PHPUnit测试覆盖特性(您需要启用)XDebug第一个):

1
。/供应商/ bin / phpunit)——coverage-html = x /

开放example.com/cov/src/Simplex/Framework.php.html在浏览器中检查框架类的所有行是否都是绿色的(这意味着在执行测试时它们已经被访问过)。

或者你可以直接将结果输出到控制台:

1
/供应商/ bin / phpunit)——coverage-text

感谢到目前为止我们所编写的干净的面向对象代码,我们已经能够编写单元测试来覆盖我们框架的所有可能用例;test double确保我们实际上是在测试我们的代码,而不是Symfony代码。ob娱乐下载

现在我们(再次)对所编写的代码有了信心,我们可以放心地考虑我们想要添加到框架中的下一批特性。

此工作,包括代码示例,是根据创作共用BY-SA 3.0许可证。
ob娱乐下载Symfony 6.2支持通过苏禄人
ob娱乐下载Symfony 6.2支持通过Les-Tilleuls.coop