{"id":1097,"date":"2025-06-12T12:51:49","date_gmt":"2025-06-12T04:51:49","guid":{"rendered":"https:\/\/www.zhaozhao123.cn\/php\/php-application-manual\/symfony\/1097.html"},"modified":"2025-06-12T12:51:49","modified_gmt":"2025-06-12T04:51:49","slug":"%e5%a6%82%e4%bd%95%e5%9c%a8-symfony-%e4%b8%ad%e7%bc%96%e5%86%99%e5%8d%95%e5%85%83%e6%b5%8b%e8%af%95%ef%bc%9a%e5%ae%9e%e8%b7%b5%e6%8c%87%e5%8d%97","status":"publish","type":"my1js","link":"https:\/\/www.zhaozhao123.cn\/php\/my1js\/1097.html","title":{"rendered":"\u5982\u4f55\u5728 Symfony \u4e2d\u7f16\u5199\u5355\u5143\u6d4b\u8bd5\uff1a\u5b9e\u8df5\u6307\u5357"},"content":{"rendered":"<div class=\"wp-block-columns p-0 border is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-columns px-4 py-3 border-bottom has-background is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\" style=\"background:linear-gradient(243deg,rgb(238,238,238) 0%,rgba(58,166,242,0.15) 100%)\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-6c531013 wp-block-group-is-layout-flex\">\r\n<figure class=\"wp-block-image size-thumbnail is-resized is-style-rounded is-style-rounded--1\"><img decoding=\"async\" src=\"https:\/\/www.zhaozhao123.cn\/myitems\/images\/sites16\/2025\/06\/dyA-1-400x300.jpg\" alt=\"Bug&#32534;&#35793;&#29422;\" class=\"wp-image-1842\" style=\"object-fit:cover;width:30px;height:30px\"><\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading my-0\" style=\"font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.175), 1rem);\">Bug&#32534;&#35793;&#29422;<\/h2>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"wp-block-columns px-xl-5 px-4 py-xl-4 py-3 is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<p>&#22312; Symfony &#20013;&#32534;&#20889;&#21333;&#20803;&#27979;&#35797;&#26159;&#19968;&#20010;&#37325;&#35201;&#30340;&#36807;&#31243;&#65292;&#23427;&#26377;&#21161;&#20110;&#30830;&#20445;&#20195;&#30721;&#30340;&#27491;&#30830;&#24615;&#21644;&#20581;&#22766;&#24615;&#12290;&#20197;&#19979;&#26159;&#19968;&#20123;&#22522;&#26412;&#30340;&#23454;&#36341;&#25351;&#21335;&#21644;&#31034;&#20363;&#20195;&#30721;&#65292;&#24110;&#21161;&#20320;&#22312; Symfony &#39033;&#30446;&#20013;&#32534;&#20889;&#26377;&#25928;&#30340;&#21333;&#20803;&#27979;&#35797;&#12290;<\/p>\n<h3>1. &#23433;&#35013;&#24517;&#35201;&#30340;&#24037;&#20855;<\/h3>\n<p>&#39318;&#20808;&#65292;&#30830;&#20445;&#20320;&#24050;&#32463;&#23433;&#35013;&#20102; PHPUnit &#21644; Composer&#12290;&#22914;&#26524;&#27809;&#26377;&#23433;&#35013;&#65292;&#21487;&#20197;&#20351;&#29992;&#20197;&#19979;&#21629;&#20196;&#36827;&#34892;&#23433;&#35013;&#65306;<\/p>\n<pre><code class=\"language-bash\">composer require --dev phpunit\/phpunit<\/code><\/pre>\n<h3>2. &#21019;&#24314;&#27979;&#35797;&#30446;&#24405;<\/h3>\n<p>&#22312;&#20320;&#30340; Symfony &#39033;&#30446;&#26681;&#30446;&#24405;&#19979;&#21019;&#24314;&#19968;&#20010; <code>tests<\/code> &#30446;&#24405;&#65292;&#24182;&#22312;&#20854;&#20013;&#21019;&#24314;&#19968;&#20010;&#26032;&#30340;&#27979;&#35797;&#31867;&#25991;&#20214;&#12290;<\/p>\n<p>&#20363;&#22914;&#65292;&#22914;&#26524;&#20320;&#26377;&#19968;&#20010;&#25511;&#21046;&#22120; <code>AppControllerHelloController.php<\/code>&#65292;&#20320;&#21487;&#20197;&#21019;&#24314;&#19968;&#20010;&#23545;&#24212;&#30340;&#27979;&#35797;&#31867; <code>src\/Tests\/Controller\/HelloControllerTest.php<\/code>&#12290;<\/p>\n<h3>3. &#32534;&#20889;&#27979;&#35797;&#31867;<\/h3>\n<p>&#22312;&#27979;&#35797;&#31867;&#20013;&#65292;&#20351;&#29992; PHPUnit &#25552;&#20379;&#30340; assertions&#26469;&#39564;&#35777;&#25511;&#21046;&#22120;&#30340;&#34892;&#20026;&#12290;<\/p>\n<pre><code class=\"language-php\">&lt;?php\n\nnamespace AppTestsController;\n\nuse SymfonyBundleFrameworkBundleTestWebTestCase;\nuse SymfonyComponentHttpFoundationResponse;\n\nclass HelloControllerTest extends WebTestCase\n{\n    public function testIndexAction()\n    {\n        $client = static::createClient();\n\n        $response = $client-&gt;request('GET', '\/hello');\n\n        $this-&gt;assertEquals(Response::HTTP_OK, $response-&gt;getStatusCode());\n        $this-&gt;assertContains('Hello World!', $response-&gt;getContent());\n    }\n}<\/code><\/pre>\n<p>&#22312;&#36825;&#20010;&#31034;&#20363;&#20013;&#65292;&#25105;&#20204;&#20351;&#29992; <code>WebTestCase<\/code> &#31867;&#26469;&#27169;&#25311; HTTP &#35831;&#27714;&#65292;&#24182;&#20351;&#29992; <code>assertEqual<\/code> &#21644; <code>assertContains<\/code> &#26469;&#39564;&#35777;&#21709;&#24212;&#30340;&#29366;&#24577;&#30721;&#21644;&#20869;&#23481;&#12290;<\/p>\n<h3>4. &#36816;&#34892;&#27979;&#35797;<\/h3>\n<p>&#22312;&#32456;&#31471;&#20013;&#36816;&#34892;&#20197;&#19979;&#21629;&#20196;&#26469;&#25191;&#34892;&#27979;&#35797;&#65306;<\/p>\n<pre><code class=\"language-bash\">.\/bin\/phpunit tests<\/code><\/pre>\n<p>&#22914;&#26524;&#25152;&#26377;&#27979;&#35797;&#36890;&#36807;&#65292;&#20320;&#20250;&#30475;&#21040;&#31867;&#20284;&#22914;&#19979;&#30340;&#36755;&#20986;&#65306;<\/p>\n<pre><code>PHPUnit 9.5.8 by Sebastian Bergmann and contributors.\n\nF                                                                  1 \/ 1 (100%)\n\nTime: 0.007 seconds, Memory: 6.00 MB\n\nThere was 1 failure:\n\n1) AppTestsControllerHelloControllerTest::testIndexAction\nFailed asserting that response status code is 200.\nExpected 200 but got 404.<\/code><\/pre>\n<h3>5. &#25193;&#23637;&#27979;&#35797;<\/h3>\n<p>&#20026;&#20102;&#36827;&#19968;&#27493;&#25552;&#39640;&#27979;&#35797;&#35206;&#30422;&#29575;&#65292;&#21487;&#20197;&#28155;&#21152;&#26356;&#22810;&#30340;&#27979;&#35797;&#29992;&#20363;&#65292;&#20363;&#22914;&#19981;&#21516;&#30340;&#35831;&#27714;&#26041;&#27861;&#12289;&#29366;&#24577;&#30721;&#31561;&#12290;<\/p>\n<pre><code class=\"language-php\">public function testGetActionWithQueryString()\n{\n    $client = static::createClient();\n    $client-&gt;request('GET', '\/hello?name=World');\n\n    $this-&gt;assertEquals(Response::HTTP_OK, $client-&gt;getResponse()-&gt;getStatusCode());\n    $this-&gt;assertContains('Hello World!', $client-&gt;getResponse()-&gt;getContent());\n}<\/code><\/pre>\n<h3>6. &#20351;&#29992; fixtures&#65288;&#21487;&#36873;&#65289;<\/h3>\n<p>&#22914;&#26524;&#20320;&#38656;&#35201;&#22312;&#27979;&#35797;&#20013;&#20351;&#29992;&#25968;&#25454;&#24211;&#25968;&#25454;&#65292;&#21487;&#20197;&#20351;&#29992; Symfony &#30340; Fixtures &#21253;&#12290;<\/p>\n<pre><code class=\"language-yaml\"># config\/packages\/dev\/doctrine.yaml\ndoctrine:\n    orm:\n        auto_generate_proxy_classes: true\n        auto_mapping: true\n        mappings:\n            AppEntity:\n                type: annotation\n                dir: '%kernel.project_dir%\/src\/Entity'\n                prefix: 'AppEntity'\n                alias: Entity\n\n# src\/DataFixtures\/AppFixtures.php\n&lt;?php\n\nnamespace AppDataFixtures;\n\nuse DoctrineBundleFixturesBundleFixture;\nuse DoctrinePersistenceObjectManager;\nuse AppEntityUser;\n\nclass AppFixtures extends Fixture\n{\n    public function load(ObjectManager $manager)\n    {\n        $user = new User();\n        $user-&gt;setUsername('john_doe');\n        $user-&gt;setEmail('john.doe@example.com');\n        $manager-&gt;persist($user);\n        $manager-&gt;flush();\n    }\n}<\/code><\/pre>\n<p>&#28982;&#21518;&#22312; <code>config\/services.yaml<\/code> &#20013;&#27880;&#20876;&#36825;&#20010; fixture&#65306;<\/p>\n<pre><code class=\"language-yaml\">services:\n    AppDataFixturesAppFixtures:\n        tags: ['doctrine.fixture']<\/code><\/pre>\n<p>&#26368;&#21518;&#65292;&#36816;&#34892;&#20197;&#19979;&#21629;&#20196;&#26469;&#21152;&#36733;&#24182;&#20351;&#29992;&#36825;&#20123;&#25968;&#25454;&#65306;<\/p>\n<pre><code class=\"language-bash\">.\/bin\/console doctrine:fixtures:load<\/code><\/pre>\n<p>&#36890;&#36807;&#36825;&#20123;&#27493;&#39588;&#65292;&#20320;&#21487;&#20197;&#22312; Symfony &#39033;&#30446;&#20013;&#26377;&#25928;&#22320;&#32534;&#20889;&#21644;&#36816;&#34892;&#21333;&#20803;&#27979;&#35797;&#12290;<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div><div class=\"wp-block-columns p-0 border is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-columns px-4 py-3 border-bottom has-background is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\" style=\"background:linear-gradient(243deg,rgb(238,238,238) 0%,rgba(58,166,242,0.15) 100%)\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-6c531013 wp-block-group-is-layout-flex\">\r\n<figure class=\"wp-block-image size-thumbnail is-resized is-style-rounded is-style-rounded--2\"><img decoding=\"async\" src=\"https:\/\/www.zhaozhao123.cn\/myitems\/images\/sites16\/2025\/06\/zp-400x300.jpg\" alt=\"&#40657;&#26495;Bug&#35762;&#24072;\" class=\"wp-image-1849\" style=\"object-fit:cover;width:30px;height:30px\"><\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading my-0\" style=\"font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.175), 1rem);\">&#40657;&#26495;Bug&#35762;&#24072;<\/h2>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"wp-block-columns px-xl-5 px-4 py-xl-4 py-3 is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<body><h3>&#20171;&#32461;<\/h3><p>&#21333;&#20803;&#27979;&#35797;&#26159;&#36719;&#20214;&#24320;&#21457;&#24490;&#29615;&#20013;&#30340;&#19968;&#20010;&#19981;&#21487;&#25110;&#32570;&#30340;&#37096;&#20998;&#65292;&#29305;&#21035;&#26159;&#38024;&#23545;&#21333;&#20803;&#27979;&#35797;&#26469;&#35828;&#65292;&#23427;&#26377;&#21161;&#20110;&#24320;&#21457;&#32773;&#39564;&#35777;&#20854;&#24212;&#29992;&#20013;&#30340;&#21508;&#20010;&#32452;&#20214;&#26159;&#21542;&#25353;&#39044;&#26399;&#24037;&#20316;&#12290;Symfony &#26159;&#19968;&#20010;&#25552;&#20513;&#27979;&#35797;&#30340;PHP&#26694;&#26550;&#65292;&#23427;&#25552;&#20379;&#20102;&#24037;&#20855;&#26469;&#36741;&#21161;&#36825;&#19968;&#36807;&#31243;&#12290;&#22312;&#26412;&#25351;&#21335;&#20013;&#65292;&#25105;&#20204;&#23558;&#36890;&#36807;&#23454;&#38469;&#25805;&#20316;&#30340;&#26041;&#24335;&#25506;&#35752;&#22914;&#20309;&#20351;&#29992;PHPUnit&#32534;&#20889;Symfony&#30340;&#21333;&#20803;&#27979;&#35797;&#12290;<\/p><h3>&#22312;Symfony&#20013;&#35774;&#32622;PHPUnit&#12290;<\/h3><p>&#22312;&#32534;&#20889;&#27979;&#35797;&#20043;&#21069;&#65292;&#35831;&#30830;&#20445;&#24050;&#35774;&#32622;PHPUnit&#12290;Symfony Flex&#20250;&#33258;&#21160;&#23558;PHPUnit&#28155;&#21152;&#21040;&#20320;&#30340;&#39033;&#30446;&#20013;&#12290;&#22914;&#26524;&#27809;&#26377;&#23433;&#35013;&#65292;&#20320;&#21487;&#20197;&#20351;&#29992;Composer&#36827;&#34892;&#28155;&#21152;&#65306;<\/p><pre><code>composer require --dev phpunit<\/code><\/pre><p>&#23433;&#35013;&#21518;&#65292;&#37197;&#32622; PHPUnit &#35831;&#32534;&#36753;&#20197;&#19979;&#25991;&#20214;&#65306;<code>phpunit.xml.dist<\/code>&#23558;&#25991;&#20214;&#19978;&#20256;&#21040;&#24744;&#30340;&#39033;&#30446;&#20013;&#65292;&#20197;&#27491;&#30830;&#35774;&#32622;&#27979;&#35797;&#29615;&#22659;&#12290;<\/p><h3>&#29702;&#35299;&#21333;&#20803;&#27979;&#35797;&#30340;&#22522;&#30784;<\/h3><p>&#21333;&#20803;&#27979;&#35797;&#28041;&#21450;&#22312;&#38548;&#31163;&#30340;&#24773;&#20917;&#19979;&#23545;&#24212;&#29992;&#31243;&#24207;&#30340;&#26368;&#23567;&#37096;&#20998;&#36827;&#34892;&#27979;&#35797;&#65288;&#20363;&#22914;&#65292;&#19968;&#20010;&#21333;&#29420;&#30340;&#31867;&#65289;&#12290;&#19968;&#20010;&#22909;&#30340;&#21333;&#20803;&#27979;&#35797;&#24212;&#35813;&#65306;<\/p><p>&#24555;&#36895;&#25191;&#34892;<\/p><p>&#21487;&#20197;&#37325;&#22797;&#24471;&#21040;&#30456;&#21516;&#30340;&#32467;&#26524;&#12290;<\/p><p>&#29420;&#31435;&#20110;&#20854;&#20182;&#27979;&#35797;<\/p><p>&#31616;&#27905;&#65292;&#27979;&#35797;&#20195;&#30721;&#30340;&#19968;&#20010;&#26041;&#38754;&#12290;<\/p><h3>&#21019;&#24314;&#24744;&#30340;&#31532;&#19968;&#20010;&#21333;&#20803;&#27979;&#35797;<\/h3><p>&#22914;&#26524;&#30446;&#24405;&#19981;&#23384;&#22312;&#65292;&#21019;&#24314;&#19968;&#20010;&#29992;&#20110;&#27979;&#35797;&#30340;&#30446;&#24405;&#65288;&#36890;&#24120;&#24773;&#20917;&#19979;&#65289;<code>tests\/<\/code>&#22909;&#30340;&#65292;&#25105;&#26126;&#30333;&#20102;&#12290;&#35831;&#25552;&#20379;&#38656;&#35201;&#32763;&#35793;&#30340;&#25991;&#26412;&#12290;<\/p><pre><code>&lt;?php\nnamespace AppTestsService;\n\nuse AppServiceCalculator;\nuse PHPUnitFrameworkTestCase;\n\nclass CalculatorTest extends TestCase\n{\n    public function testAdd()\n    {\n        $calculator = new Calculator();\n        $result = $calculator-&gt;add(30, 12);\n        $this-&gt;assertEquals(42, $result);\n    }\n}\n<\/code><\/pre><p>&#36825;&#20010;&#20195;&#30721;&#27979;&#35797;&#20102;&#19968;&#20010;<code>add<\/code>&#26041;&#27861;&#22312;&#20854;&#20013;<code>Calculator<\/code>&#26381;&#21153;&#31867;&#12290;<\/p><h3>&#36816;&#34892;&#24744;&#30340;Symfony&#21333;&#20803;&#27979;&#35797;<\/h3><p>&#22312;&#38598;&#25104;PHPUnit&#21518;&#65292;&#24744;&#21487;&#20197;&#20351;&#29992;&#20197;&#19979;&#21629;&#20196;&#36816;&#34892;&#27979;&#35797;&#65306;<\/p><pre><code>.\/bin\/phpunit<\/code><\/pre><p>PHPUnit &#23558;&#33258;&#21160;&#21457;&#29616;&#21644;&#25191;&#34892;&#27979;&#35797;&#12290;<code>tests\/<\/code>&#30446;&#24405;&#12290;<\/p><h3>&#32534;&#20889;&#39640;&#36136;&#37327;&#30340;&#21333;&#20803;&#27979;&#35797;<\/h3><p>&#20197;&#19979;&#26159;&#32534;&#20889;&#21333;&#20803;&#27979;&#35797;&#26102;&#30340;&#19968;&#20123;&#26368;&#20339;&#23454;&#36341;&#65306;<\/p><p>&#20351;&#29992;&#22914;&#20869;&#32622;&#30340;PHPUnit Mocks&#25110;Mockery&#31561;&#24037;&#20855;&#26469;&#27169;&#25311;&#20381;&#36182;&#39033;&#12290;<\/p><p>&#27979;&#35797;&#26631;&#20934;&#29992;&#20363;&#21644;&#36793;&#32536;&#24773;&#20917;<\/p><p>&#20445;&#25345;&#27979;&#35797;&#19987;&#27880;&#20110;&#21333;&#19968;&#30340;&#21151;&#33021;&#25110;&#26041;&#27861;&#12290;<\/p><p>&#20351;&#29992;&#25551;&#36848;&#24615;&#30340;&#27979;&#35797;&#26041;&#27861;&#21517;&#31216;&#65288;&#20363;&#22914;&#65306;&#65289;<code>testAdditionWithPositiveNumbers<\/code>&#24050;&#32463;&#25910;&#21040;&#65292;&#35831;&#38382;&#26377;&#20160;&#20040;&#25105;&#21487;&#20197;&#24110;&#21161;&#30340;&#21527;&#65311;<\/p><h3>&#22312;Symfony&#26694;&#26550;&#20013;&#65292;mock&#23545;&#35937;&#26159;&#19968;&#31181;&#38750;&#24120;&#26377;&#29992;&#30340;&#24037;&#20855;&#65292;&#29992;&#20110;&#27169;&#25311;&#20381;&#36182;&#20851;&#31995;&#21644;&#27979;&#35797;&#31867;&#30340;&#34892;&#20026;&#12290;&#36890;&#36807;&#20351;&#29992;mock&#23545;&#35937;&#65292;&#20320;&#21487;&#20197;&#36731;&#26494;&#22320;&#21019;&#24314;&#19968;&#20010;&#20855;&#26377;&#29305;&#23450;&#34892;&#20026;&#30340;&#23545;&#35937;&#23454;&#20363;&#65292;&#32780;&#26080;&#38656;&#23454;&#38469;&#21019;&#24314;&#23427;&#12290;&#36825;&#20351;&#24471;&#32534;&#20889;&#21333;&#20803;&#27979;&#35797;&#21464;&#24471;&#26356;&#21152;&#31616;&#21333;&#21644;&#26377;&#25928;&#12290;\n&#20197;&#19979;&#26159;&#20351;&#29992;mock&#23545;&#35937;&#30340;&#19968;&#20123;&#24120;&#35265;&#26041;&#27861;&#65306;\n\n&#21019;&#24314;mock&#23545;&#35937;&#65306;&#39318;&#20808;&#38656;&#35201;&#23548;&#20837;phpunitmockPHPUnit_Framework_MockObject_MockObject&#31867;&#12290;\nuse PHPUnitFrameworkTestCase;\nuse PHPUnitFrameworkMockObjectMockObject;\n\nclass MyClassTest extends TestCase {\n protected $mock;\n\n public function setUp() {\n parent::setUp();\n $this-&gt;mock = $this-&gt;getMockBuilder(MyClass::class)\n -&gt;setMethods([&#8216;someMethod&#8217;])\n -&gt;getMockForAbstractClass();\n }\n\n public function testSomeMethod() {\n \/\/ &#20351;&#29992;$mock-&gt;expects($this-&gt;once())-&gt;method(&#8216;someMethod&#8217;)-&gt;willReturn(42);\n \/\/ &#31561;&#21516;&#20110;&#35843;&#29992;$mock-&gt;someMethod()-&gt;willReturn(42);\n\n $this-&gt;assertEquals(42, $this-&gt;mock-&gt;someMethod());\n }\n}\n\n&#35774;&#32622;&#26399;&#26395;&#20540;&#65306;&#20351;&#29992;expects()&#26041;&#27861;&#26469;&#35774;&#32622;&#26399;&#26395;&#30340;&#36820;&#22238;&#20540;&#25110;&#35843;&#29992;&#27425;&#25968;&#31561;&#26465;&#20214;&#12290;\n$this-&gt;mock-&gt;expects($this-&gt;once())\n -&gt;method(&#8216;someMethod&#8217;)\n -&gt;will($this-&gt;returnCallback(function () { return 42; }));\n\n&#39564;&#35777;&#26041;&#27861;&#35843;&#29992;&#65306;&#21487;&#20197;&#36890;&#36807;&#35843;&#29992;assertThat()&#26041;&#27861;&#26469;&#39564;&#35777;&#26041;&#27861;&#26159;&#21542;&#34987;&#27491;&#30830;&#35843;&#29992;&#12290;\n$this-&gt;assertTrue($this-&gt;mock-&gt;someMethodCalled());\n\n&#33258;&#23450;&#20041;&#23454;&#29616;&#65306;&#22914;&#26524;&#38656;&#35201;&#20462;&#25913;mock&#23545;&#35937;&#30340;&#34892;&#20026;&#65292;&#21487;&#20197;&#37325;&#20889;&#20854;&#29238;&#31867;&#30340;&#26041;&#27861;&#12290;\nabstract class AbstractMyClass {\n abstract public function someMethod();\n}\n\nclass MyClass extends AbstractMyClass {\n public function someMethod() {\n return &#8216;Hello, World!&#8217;;\n }\n}\n\n\/\/ &#21019;&#24314;mock&#23545;&#35937;&#24182;&#35206;&#30422;&#29238;&#31867;&#26041;&#27861;\n$myClass = new MockObject(AbstractMyClass::class);\n$myClass-&gt;method(&#8216;someMethod&#8217;) \n -&gt;will($this-&gt;returnValue(&#8216;Custom Hello, World!&#8217;));\n\n&#26029;&#35328;&#38169;&#35823;&#20449;&#24687;&#65306;&#20351;&#29992;assertThrowsException()&#26041;&#27861;&#26469;&#26816;&#26597;&#26159;&#21542;&#23384;&#22312;&#39044;&#26399;&#30340;&#24322;&#24120;&#12290;\ntry {\n $this-&gt;mock-&gt;someMethod();\n} catch (Exception $e) {\n $this-&gt;assertInstanceOf(Exception::class, $e);\n $this-&gt;assertEquals(&#8220;Expected exception&#8221;, $e-&gt;getMessage());\n}\n\n&#36890;&#36807;&#36825;&#20123;&#26041;&#27861;&#65292;&#24320;&#21457;&#32773;&#21487;&#20197;&#22312;&#19981;&#23454;&#38469;&#21019;&#24314;&#23545;&#35937;&#30340;&#24773;&#20917;&#19979;&#27979;&#35797;&#20195;&#30721;&#30340;&#34892;&#20026;&#65292;&#20174;&#32780;&#25552;&#39640;&#27979;&#35797;&#25928;&#29575;&#21644;&#35206;&#30422;&#29575;&#12290;<\/h3><p>&#26377;&#26102;&#20320;&#38656;&#35201;&#27979;&#35797;&#20381;&#36182;&#20110;&#20854;&#20182;&#32452;&#20214;&#30340;&#31867;&#12290;Mock&#23545;&#35937;&#27169;&#25311;&#36825;&#20123;&#20381;&#36182;&#34892;&#20026;&#12290;&#19979;&#38754;&#26159;&#21019;&#24314;Mock&#30340;&#26041;&#27861;&#65306;<\/p><pre><code>$mock = $this-&gt;createMock(SomeClass::class);\n$mock-&gt;method('someMethod')\n       -&gt;willReturn('someValue');<\/code><\/pre><h3>&#27979;&#35797;&#39537;&#21160;&#24320;&#21457;&#65288;TDD&#65289;&#22312;Symfony&#20013;&#30340;&#24212;&#29992;<\/h3><p>TDD &#26159;&#19968;&#31181;&#36719;&#20214;&#24320;&#21457;&#36807;&#31243;&#65292;&#22312;&#27492;&#36807;&#31243;&#20013;&#65292;&#24744;&#22312;&#20195;&#30721;&#35201;&#27979;&#35797;&#20043;&#21069;&#32534;&#20889;&#27979;&#35797;&#12290;&#36825;&#36890;&#24120;&#20250;&#23548;&#33268;&#26356;&#24443;&#24213;&#30340;&#27979;&#35797;&#21644;&#26356;&#25972;&#27905;&#30340;&#20195;&#30721;&#12290;&#20197;&#19979;&#26159;&#22914;&#20309;&#36981;&#24490; TDD &#22312;&#26032; Symfony &#21151;&#33021;&#19978;&#30340;&#27493;&#39588;&#65306;<\/p><p>&#20248;&#21270;&#20195;&#30721;&#65292;&#30830;&#20445;&#26356;&#25913;&#21518;&#27979;&#35797;&#20173;&#28982;&#36890;&#36807;&#12290;<\/p><p>&#32534;&#20889;&#24517;&#35201;&#30340;&#20195;&#30721;&#20197;&#36890;&#36807;&#27979;&#35797;&#12290;<\/p><p>&#36816;&#34892;&#27979;&#35797;&#65288;&#29616;&#22312;&#24212;&#35813;&#22312;&#27492;&#22788;&#22833;&#36133;&#65289;<\/p><p>&#32534;&#20889;&#19968;&#20010;&#27979;&#35797;&#20197;&#39564;&#35777;&#25152;&#38656;&#21151;&#33021;&#12290;<\/p><h3>&#19982;Symfony&#38598;&#25104;<\/h3><p>&#34429;&#28982;&#25105;&#20204;&#19987;&#27880;&#20110;&#21333;&#20803;&#27979;&#35797;&#65292;&#20294;Symfony&#20063;&#25552;&#20379;&#20102;&#29992;&#20110;&#21151;&#33021;&#27979;&#35797;&#30340;&#21151;&#33021;&#65292;&#36825;&#23545;&#20110;&#27979;&#35797;&#22810;&#20010;&#32452;&#20214;&#22914;&#20309;&#21327;&#21516;&#24037;&#20316;&#38750;&#24120;&#26377;&#24110;&#21161;&#12290;&#20363;&#22914;&#65292;&#26381;&#21153;&#22914; HttpKernel &#21487;&#20197;&#29992;&#26469;&#27169;&#25311; HTTP &#35831;&#27714;&#21644;&#21709;&#24212;&#12290;<code>KernelTestCase<\/code>and the<code>WebTestCase<\/code>&#20801;&#35768;&#24744;&#21551;&#21160;&#20869;&#26680;&#24182;&#27169;&#25311;HTTP&#35831;&#27714;&#65292;&#20197;&#20415;&#36827;&#34892;&#26356;&#20840;&#38754;&#30340;&#27979;&#35797;&#22871;&#20214;&#12290;<\/p><h3>&#22312;&#27979;&#35797;&#20013;&#22788;&#29702;&#25968;&#25454;&#24211;&#30340;&#25552;&#31034;&#65306;<\/h3><p>&#22312;&#22788;&#29702;&#25968;&#25454;&#24211;&#26102;&#65292;&#27599;&#27425;&#27979;&#35797;&#21518;&#30830;&#20445;&#37325;&#32622;&#29366;&#24577;&#20197;&#36991;&#20813;&#27979;&#35797;&#20043;&#38388;&#30340;&#20132;&#20114;&#12290;Doctrine &#30340;&#24037;&#20855;&#23601;&#38750;&#24120;&#26377;&#29992;&#12290;<code>DataFixtures<\/code>&#21487;&#20197;&#38750;&#24120;&#26041;&#20415;&#22320;&#29992;&#20110;&#35774;&#32622;&#21644;&#28165;&#29702;&#27979;&#35797;&#25968;&#25454;&#12290;<\/p><h3>&#25345;&#32493;&#38598;&#25104;<\/h3><p>&#23558;PHPUnit&#27979;&#35797;&#38598;&#25104;&#21040;&#25345;&#32493;&#38598;&#25104;&#65288;CI&#65289;&#31649;&#36947;&#20013;&#30830;&#20445;&#22312;&#20363;&#22914;&#27599;&#27425;&#23545;&#20179;&#24211;&#36827;&#34892;&#25512;&#36865;&#21040;&#26102;&#33258;&#21160;&#36816;&#34892;&#27979;&#35797;&#12290;Symfony&#19982;CI&#24037;&#20855;&#22914;Jenkins&#12289;Travis CI&#25110;GitHub Actions&#24456;&#22909;&#22320;&#38598;&#25104;&#12290;<\/p><h3>&#32467;&#35770;&#12290;<\/h3><p>&#21333;&#20803;&#27979;&#35797;&#23545;&#20110;&#20445;&#25345;&#39640;&#36136;&#37327;&#20195;&#30721;&#33267;&#20851;&#37325;&#35201;&#12290;&#36890;&#36807;&#23558;PHPUnit&#27979;&#35797;&#38598;&#25104;&#21040;Symfony&#24320;&#21457;&#27969;&#31243;&#20013;&#65292;&#24744;&#19981;&#20165;&#30830;&#20445;&#32452;&#20214;&#22312;&#38548;&#31163;&#24773;&#20917;&#19979;&#24037;&#20316;&#33391;&#22909;&#65292;&#36824;&#33021;&#22312;&#38382;&#39064;&#21040;&#36798;&#29983;&#20135;&#29615;&#22659;&#20043;&#21069;&#25429;&#33719;&#36825;&#20123;&#38382;&#39064;&#12290;&#23613;&#21487;&#33021;&#37319;&#29992;TDD&#65288;&#27979;&#35797;&#39537;&#21160;&#24320;&#21457;&#65289;&#26041;&#27861;&#65292;&#21033;&#29992;Symfony&#30340;&#21508;&#31181;&#27979;&#35797;&#24037;&#20855;&#65292;&#24182;&#20139;&#21463;&#26356;&#25972;&#27905;&#12289;&#26356;&#23569;bug&#30340;&#20195;&#30721;&#12290;<\/p><\/body>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div><div class=\"wp-block-columns p-0 border is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-columns px-4 py-3 border-bottom has-background is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\" style=\"background:linear-gradient(243deg,rgb(238,238,238) 0%,rgba(58,166,242,0.15) 100%)\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<div class=\"wp-block-group is-nowrap is-layout-flex wp-container-core-group-is-layout-6c531013 wp-block-group-is-layout-flex\">\r\n<figure class=\"wp-block-image size-thumbnail is-resized is-style-rounded is-style-rounded--3\"><img decoding=\"async\" src=\"https:\/\/www.zhaozhao123.cn\/myitems\/images\/sites16\/2025\/06\/xygcfznnzczhsdmwydzhsmzzzmddnq-400x300.jpg\" alt=\"&#38271;&#24037;&#30721;&#22900;1523\" class=\"wp-image-2906\" style=\"object-fit:cover;width:30px;height:30px\"><\/figure>\r\n\r\n\r\n\r\n<h2 class=\"wp-block-heading my-0\" style=\"font-size:clamp(0.875rem, 0.875rem + ((1vw - 0.2rem) * 0.175), 1rem);\">&#38271;&#24037;&#30721;&#22900;1523<\/h2>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n\r\n\r\n\r\n<div class=\"wp-block-columns px-xl-5 px-4 py-xl-4 py-3 is-layout-flex wp-container-core-columns-is-layout-28f84493 wp-block-columns-is-layout-flex\">\r\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\r\n<p>&#22312; Symfony &#39033;&#30446;&#20013;&#32534;&#20889;&#21333;&#20803;&#27979;&#35797;&#26159;&#30830;&#20445;&#20195;&#30721;&#36136;&#37327;&#21644;&#24615;&#33021;&#30340;&#37325;&#35201;&#32452;&#25104;&#37096;&#20998;&#12290;&#20197;&#19979;&#26159;&#19968;&#20123;&#23454;&#36341;&#25351;&#21335;&#65292;&#24110;&#21161;&#24744;&#24320;&#22987;&#32534;&#20889;&#21333;&#20803;&#27979;&#35797;&#65306;<\/p>\n<h3>1. &#23433;&#35013; PHPUnit<\/h3>\n<p>&#39318;&#20808;&#65292;&#30830;&#20445;&#24744;&#30340;&#31995;&#32479;&#19978;&#23433;&#35013;&#20102; PHP &#30340; <code>PHPUnit<\/code> &#26694;&#26550;&#12290;&#22914;&#26524;&#27809;&#26377;&#65292;&#35831;&#36890;&#36807;&#20197;&#19979;&#21629;&#20196;&#36827;&#34892;&#23433;&#35013;&#65306;<\/p>\n<pre><code class=\"language-bash\">composer require phpunit\/phpunit<\/code><\/pre>\n<h3>2. &#21019;&#24314;&#27979;&#35797;&#25991;&#20214;&#22841;&#21644;&#21333;&#20803;&#27979;&#35797;&#31867;<\/h3>\n<p>&#21019;&#24314;&#19968;&#20010;&#26032;&#30340;&#27979;&#35797;&#25991;&#20214;&#22841;&#65288;&#20363;&#22914; <code>Tests\/Unit<\/code>&#65289;&#65292;&#28982;&#21518;&#22312;&#20854;&#20013;&#21019;&#24314;&#27979;&#35797;&#31867;&#65292;&#22914; <code>TestMyBundleMyControllerTest.php<\/code>&#12290;<\/p>\n<h3>3. &#32534;&#20889;&#21333;&#20803;&#27979;&#35797;&#20195;&#30721;<\/h3>\n<p>&#22312;&#27979;&#35797;&#31867;&#20013;&#23450;&#20041;&#27979;&#35797;&#26041;&#27861;&#65292;&#36825;&#20123;&#26041;&#27861;&#23558;&#27169;&#25311;&#19994;&#21153;&#36923;&#36753;&#24182;&#26816;&#26597;&#39044;&#26399;&#30340;&#34892;&#20026;&#12290;&#20363;&#22914;&#65292;&#22914;&#26524;&#24744;&#30340;&#25511;&#21046;&#22120;&#22788;&#29702;&#29992;&#25143;&#30331;&#24405;&#35831;&#27714;&#65292;&#24744;&#21487;&#20197;&#32534;&#20889;&#22914;&#19979;&#27979;&#35797;&#26041;&#27861;&#26469;&#39564;&#35777;&#20854;&#21151;&#33021;&#65306;<\/p>\n<pre><code class=\"language-php\">&lt;?php\nnamespace TestsUnit;\n\nuse SymfonyBundleFrameworkBundleTestWebTestCase;\nuse SymfonyComponentHttpFoundationRequest;\nuse SymfonyComponentHttpFoundationResponse;\nuse SymfonyComponentHttpKernelExceptionNotFoundHttpException;\n\nclass MyControllerTest extends WebTestCase\n{\n    public function testLogin()\n    {\n        $client = static::createClient();\n\n        \/\/ &#21019;&#24314;&#19968;&#20010;&#35831;&#27714;&#23454;&#20363;\n        $request = new Request();\n        $request-&gt;headers['Accept'] = 'application\/json';\n        $request-&gt;cookies['_csrf_token'] = 'your_csrf_token';\n\n        \/\/ &#21457;&#36865;&#30331;&#24405;&#35831;&#27714;&#21040;&#25511;&#21046;&#22120;&#30340;URL\n        $response = $client-&gt;request('POST', '\/api\/login', $request);\n\n        \/\/ &#39564;&#35777;&#21709;&#24212;&#26159;&#21542;&#20026; 200 &#29366;&#24577;&#30721;\n        $this-&gt;assertEquals(200, $response-&gt;getStatusCode());\n\n        \/\/ &#39564;&#35777;&#36820;&#22238;&#30340;&#25968;&#25454;&#32467;&#26500;&#26159;&#21542;&#31526;&#21512;&#39044;&#26399;\n        $data = json_decode($response-&gt;getContent(), true);\n        $this-&gt;assertArrayHasKey('token', $data);\n    }\n}<\/code><\/pre>\n<h3>4. &#27979;&#35797;&#37197;&#32622;<\/h3>\n<p>&#22312; <code>web.xml<\/code> &#25991;&#20214;&#20013;&#65292;&#35774;&#32622; <code>test-classes<\/code> &#23646;&#24615;&#20197;&#25351;&#23450;&#38656;&#35201;&#27979;&#35797;&#30340;&#25511;&#21046;&#22120;&#31867;&#36335;&#24452;&#65306;<\/p>\n<pre><code class=\"language-xml\">&lt;web-app&gt;\n   &lt;listener&gt;\n       &lt;listener-class&gt;org.springframework.test.web.servlet.MockMvcRequestListener&lt;\/listener-class&gt;\n   &lt;\/listener&gt;\n   &lt;!-- &#35774;&#32622;&#27979;&#35797;&#31867; --&gt;\n   &lt;context-param&gt;\n       &lt;param-name&gt;test-classes&lt;\/param-name&gt;\n       &lt;param-value&gt;\/tests\/Unit\/*ControllerTest&lt;\/param-value&gt;\n   &lt;\/context-param&gt;\n&lt;\/web-app&gt;<\/code><\/pre>\n<h3>5. &#20351;&#29992; Composer &#21629;&#20196;&#34892;&#24037;&#20855;&#36816;&#34892;&#27979;&#35797;<\/h3>\n<p>&#20351;&#29992; Composer &#21629;&#20196;&#34892;&#24037;&#20855;&#25191;&#34892;&#21333;&#20803;&#27979;&#35797;&#12290;&#39318;&#20808;&#65292;&#25171;&#24320;&#21629;&#20196;&#34892;&#30028;&#38754;&#65292;&#23548;&#33322;&#21040;&#39033;&#30446;&#30340;&#26681;&#30446;&#24405;&#65292;&#24182;&#36816;&#34892;&#20197;&#19979;&#21629;&#20196;&#65306;<\/p>\n<pre><code class=\"language-bash\">vendor\/bin\/phpunit --configuration=composer.json<\/code><\/pre>\n<p>&#36825;&#23558;&#33258;&#21160;&#21152;&#36733;&#25152;&#26377; <code>Test<\/code> &#30446;&#24405;&#19979;&#30340;&#27979;&#35797;&#25991;&#20214;&#65292;&#24182;&#36816;&#34892;&#23427;&#20204;&#12290;&#27880;&#24847;&#65292;Composer JSON &#37197;&#32622;&#25991;&#20214;&#20013;&#30340; <code>compoers.json<\/code> &#25991;&#20214;&#29992;&#20110;&#27880;&#20876;&#33258;&#23450;&#20041;&#20381;&#36182;&#39033;&#12290;<\/p>\n<h3>6. &#27979;&#35797;&#35206;&#30422;&#29575;<\/h3>\n<p>&#20026;&#20102;&#25552;&#39640;&#27979;&#35797;&#30340;&#20934;&#30830;&#24615;&#21644;&#25928;&#29575;&#65292;&#21487;&#20197;&#32771;&#34385;&#20351;&#29992;&#35832;&#22914; Codeception &#25110; Behat &#36825;&#26679;&#30340;&#26694;&#26550;&#26469;&#29983;&#25104;&#35206;&#30422;&#25253;&#21578;&#12290;Codeception &#26159;&#19968;&#31181;&#22522;&#20110;&#21333;&#20803;&#27979;&#35797;&#30340;&#27979;&#35797;&#26694;&#26550;&#65292;&#32780; Behat &#21017;&#26159;&#19968;&#31181;&#38754;&#21521;&#22330;&#26223;&#30340;&#27979;&#35797;&#39537;&#21160;&#24320;&#21457;&#26694;&#26550;&#12290;<\/p>\n<h3>&#31034;&#20363;&#20195;&#30721;<\/h3>\n<p>&#19979;&#38754;&#26159;&#19968;&#20010;&#31616;&#21333;&#30340; Controller &#23454;&#29616;&#65292;&#28436;&#31034;&#22914;&#20309;&#22312; Symfony &#20013;&#20351;&#29992; PHPUnit &#32534;&#20889;&#21333;&#20803;&#27979;&#35797;&#65306;<\/p>\n<pre><code class=\"language-php\">&lt;?php\n\nnamespace TestsController;\n\nuse SymfonyBundleFrameworkBundleTestWebTestCase;\nuse SymfonyComponentHttpFoundationResponse;\nuse SymfonyComponentRoutingAnnotationRoute;\n\nclass MyControllerTest extends WebTestCase\n{\n    \/**\n     * Test login functionality.\n     *\/\n    #[Route('\/login', name: 'my_login')]\n    public function testLogin(): Response\n    {\n        return $this-&gt;performLogin();\n    }\n\n    private function performLogin(): Response\n    {\n        $client = static::createClient();\n\n        \/\/ &#21019;&#24314;&#19968;&#20010;&#35831;&#27714;&#23454;&#20363;\n        $request = new Request();\n        $request-&gt;headers['Accept'] = 'application\/json';\n        $request-&gt;cookies['_csrf_token'] = 'your_csrf_token';\n\n        \/\/ &#21457;&#36865;&#30331;&#24405;&#35831;&#27714;&#21040;&#25511;&#21046;&#22120;&#30340;URL\n        $response = $client-&gt;request('POST', '\/api\/login', $request);\n\n        \/\/ &#39564;&#35777;&#21709;&#24212;&#26159;&#21542;&#20026; 200 &#29366;&#24577;&#30721;\n        $this-&gt;assertEquals(200, $response-&gt;getStatusCode());\n\n        \/\/ &#39564;&#35777;&#36820;&#22238;&#30340;&#25968;&#25454;&#32467;&#26500;&#26159;&#21542;&#31526;&#21512;&#39044;&#26399;\n        $data = json_decode($response-&gt;getContent(), true);\n        $this-&gt;assertArrayHasKey('token', $data);\n\n        return $response;\n    }\n}<\/code><\/pre>\n<p>&#36825;&#20010;&#20363;&#23376;&#23637;&#31034;&#20102;&#22914;&#20309;&#22312; Symfony &#20013;&#20351;&#29992; PHPUnit &#32534;&#20889;&#21333;&#20803;&#27979;&#35797;&#65292;&#24182;&#19988;&#20351;&#29992;&#20102; <code>@Route<\/code> &#27880;&#35299;&#26469;&#25351;&#23450;&#27979;&#35797;&#36335;&#30001;&#12290;&#26681;&#25454;&#23454;&#38469;&#38656;&#27714;&#65292;&#21487;&#20197;&#26681;&#25454;&#38656;&#35201;&#28155;&#21152;&#26356;&#22810;&#30340;&#27979;&#35797;&#29992;&#20363;&#12290;<\/p>\r\n<\/div>\r\n<\/div>\r\n<\/div>\r\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>Bug&#32534;&#35793;&#29422; &#22312; Symfony &#20013;&#32534;&#20889;&#21333;&#20803;&#27979;&#35797;&#26159;&#19968;&#20010;&#37325;&#35201;&#30340;&#36807;&#038;#3..<\/p>\n","protected":false},"author":1,"featured_media":0,"menu_order":0,"template":"","meta":{"_acf_changed":false},"tags":[],"my1js2nav":[45],"tuisongtax":[],"class_list":["post-1097","my1js","type-my1js","status-publish","hentry","my1js2nav-symfony"],"acf":{"qian_art_seotitle":"","qian_art_seotitle_source":{"label":"SEO\u6807\u9898","type":"text","formatted_value":""},"qian_art_seokws":"","qian_art_seokws_source":{"label":"SEO\u5173\u952e\u8bcd","type":"text","formatted_value":""},"qian_art_stzhong":"","qian_art_stzhong_source":{"label":"\u4e2d | \u77ed\u6807\u9898","type":"text","formatted_value":""}},"_links":{"self":[{"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/my1js\/1097","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/my1js"}],"about":[{"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/types\/my1js"}],"author":[{"embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/users\/1"}],"wp:attachment":[{"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/media?parent=1097"}],"wp:term":[{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/tags?post=1097"},{"taxonomy":"my1js2nav","embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/my1js2nav?post=1097"},{"taxonomy":"tuisongtax","embeddable":true,"href":"https:\/\/www.zhaozhao123.cn\/php\/wp-json\/wp\/v2\/tuisongtax?post=1097"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}