单元测试
编辑本页单元测试
你可能已经注意到我们在前一章中构建的框架中有一些微妙但重要的错误。在创建框架时,必须确保它的行为与所宣传的一致。否则,所有基于它的应用程序都将出现相同的错误。好消息是,无论何时欧宝平台是合法的吗您修复了一个错误,您都在修复一堆应用程序。
今天的任务是为我们创建的框架编写单元测试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$解析器, ArgumentResolverInterface$argumentResolver){$这->匹配器=$匹配器;$这->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娱乐下载\组件\路由\异常\ResourceNotFoundException;类FrameworkTest扩展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::类);返回新框架($匹配器,$controllerResolver,$argumentResolver);}}
此测试模拟不匹配任何路由的请求。因此,匹配()
方法返回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::类)));$controllerResolver=新ControllerResolver ();$argumentResolver=新ArgumentResolver ();$框架=新框架($匹配器,$controllerResolver,$argumentResolver);$响应=$框架->处理(新请求());$这->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娱乐下载
现在我们(再次)对所编写的代码有了信心,我们可以放心地考虑我们想要添加到框架中的下一批特性。