Juergen Schulze
Juergen Schulze

Reputation: 1644

Symfony tests, making request does not find routes

Symfony 6

According to this I am writing a WebTestCase.

The controller to be tested delivers json coded array data and works fine.

But the test itself cannot load from the URL. All I get is a 404 error.

The URL is: http://masch1/company/public/get/data?active=1&sort=desc

This is my test

<?php

// php bin/phpunit tests/Controller/DataControllerTest.php
namespace App\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class DataControllerTest extends WebTestCase
{
    public function testSomething(): void
    {
        $client = static::createClient();
        $crawler = $client->request('GET', 'http://masch1/company/public/get/data?active=1&sort=desc');

        $this->assertResponseIsSuccessful();
        $this->assertSelectorTextContains('h1', 'Hello World');
    }
}

The tutorial itself says that hardcoding the request URLs is a best practice for application tests.

In my desperation I tried different combinations.

etc.

But all I get when running is:

/var/www/company/vendor/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php:142 /var/www/company/vendor/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php:33 /var/www/company/tests/Controller/DataControllerTest.php:15

Caused by ErrorException: No route found for "GET http://localhost/company/public/get/data" in /var/www/company/vendor/symfony/http-kernel/EventListener/RouterListener.php:127 Stack trace: #0 /var/www/company/vendor/symfony/framework-bundle/Test/BrowserKitAssertionsTrait.php(33): Symfony\Bundle\FrameworkBundle\Test\WebTestCase::assertThatForResponse() #1 /var/www/company/tests/Controller/DataControllerTest.php(15): Symfony\Bundle\FrameworkBundle\Test\WebTestCase::assertResponseIsSuccessful() #2 /var/www/company/vendor/phpunit/phpunit/src/Framework/TestCase.php(1608): App\Tests\Controller\DataControllerTest->testSomething() #3 /var/www/company/vendor/phpunit/phpunit/src/Framework/TestCase.php(1214): PHPUnit\Framework\TestCase->runTest() #4 /var/www/company/vendor/phpunit/phpunit/src/Framework/TestResult.php(728): PHPUnit\Framework\TestCase->runBare() #5 /var/www/company/vendor/phpunit/phpunit/src/Framework/TestCase.php(964): PHPUnit\Framework\TestResult->run() #6 /var/www/company/vendor/phpunit/phpunit/src/Framework/TestSuite.php(684): PHPUnit\Framework\TestCase->run() #7 /var/www/company/vendor/phpunit/phpunit/src/TextUI/TestRunner.php(651): PHPUnit\Framework\TestSuite->run() #8 /var/www/company/vendor/phpunit/phpunit/src/TextUI/Command.php(144): PHPUnit\TextUI\TestRunner->run() #9 /var/www/company/vendor/phpunit/phpunit/src/TextUI/Command.php(97): PHPUnit\TextUI\Command->run() #10 /var/www/company/bin/phpunit(11): PHPUnit\TextUI\Command::main() #11 {main}

Upvotes: 0

Views: 1051

Answers (2)

Juergen Schulze
Juergen Schulze

Reputation: 1644

All i needed was the right way to insert the Url.

<?php

// php bin/phpunit tests/Controller/DataControllerTest.php
namespace App\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class DataControllerTest extends WebTestCase
{
    public function testSomething(): void
    {
        $client = static::createClient(['HTTP_HOST' => 'masch1']);
        $client->request('GET', '/get/data?active=1&sort=desc');
        $response = $client->getResponse();
        $content = $response->getContent();
        
        // Check json data with first record
        $jsonData = json_decode($content, true)[0];

        // check fields
        $this->assertArrayHasKey('field1', $jsonData);
        $this->assertArrayHasKey('field2', $jsonData);
        $this->assertArrayHasKey('field3', $jsonData);

        // Check field types
        $this->assertIsInt($jsonData['field1']);

        $this->assertEquals(200, $response->getStatusCode());

        $this->assertResponseIsSuccessful();
        
    }
}

Upvotes: 0

H8ex38Zw3bPE7ko
H8ex38Zw3bPE7ko

Reputation: 46

Might be because you used a full URL in the test instead of a relative URL. WebTestCase class automatically creates a client that simulates a browser, but it doesn't actually send HTTP requests, it directly calls the Symfony application.

Try the following code:

<?php

// php bin/phpunit tests/Controller/DataControllerTest.php
namespace App\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class DataControllerTest extends WebTestCase
{
    public function testSomething(): void
    {
        $client = static::createClient();
        // Use a relative path instead of a full URL
        $crawler = $client->request('GET', '/get/data?active=1&sort=desc');

        $this->assertResponseIsSuccessful();
        $this->assertSelectorTextContains('h1', 'Hello World');
    }
}

This way, the client will automatically use the default domain and port (usually localhost:8000) to access the application. Of course, you can also pass an array parameter when creating the client to change the default values:

$client = static::createClient(['HTTP_HOST' => 'masch1']);

For more information about the WebTestCase class and the client, refer to the following links:

Upvotes: 1

Related Questions