1
votes

I'm doing some tests with PHPUnit, but I have some problems especially when testing the Controller.

I want to test a route of a Controller by just calling the route and check if the response is a HTTP-Status 200. But alwas the Console has the smae errors.

Token Error It says something about a token that is missing. I don't have a clue what kind of token this is.

401 Error

Also this is the 401 Error he gets.

My PHPUnit-Test looks like this:

namespace App\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class PersonControllerTest extends WebTestCase { private $client;

protected function setUp()
{
    $this->client = static::createClient([], [
        'PHP_AUTH_USER' => 'user',
        'PHP_AUTH_PW'   => 'pass',
    ]);
}


public function testCreate()
{

    $this->client->request('GET','/create');

    $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
}

public function testIndex()
{

    $this->client->request('GET','/');

    $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
}

}

I have tried it with the authentication in the setUp Method -> didn't work.

Do you have any clue?

Thanks for all Answers or/and Comments

2
It is hard to come up with a solution without seeing much of your code but try adding token as 4th argument in your request method so something like this $this->client->request ........, ['HTTP_AUTHORIZATION' => 'Bearer Token']). Also if the client requires HTTPS then you should add 'HTTPS' => true. Are you using Basic auth? If so, just remove PHP_AUTH_USER and the other one then use Basic your_base_64_token_goes_here instead of Bearer above.BentCoder
Normally you wouldn't test controllers at all, at least not as part of unit testing. Controllers are supposed to contain no business logic and just serve as entry points into the application, as such all the business logic should be in separate classes that the controller simply kicks off when invoked. If you do have business logic in your controllers then your code is exhibiting an antipattern called Fat Controller.GordonM
@GordonM He/she is not unit testing his controller. What he/she is doing is that functional testing the controller which is perfectly valid - at least as far as Symfony is concerned.BentCoder

2 Answers

0
votes

Basic auth:

   /**
     * @dataProvider urlProvider
     */
    public function testPageIsSuccessful($url)
    {
        $client = self::createClient([], [
            'PHP_AUTH_USER' => getenv('PHP_AUTH_USER'),
            'PHP_AUTH_PW' => getenv('PHP_AUTH_PW')
        ]);
        $client->request('GET', $url);
        $this->assertTrue($client->getResponse()->isSuccessful());
    }

API key

    /**
     * @dataProvider urlApiProvider
     */
    public function testAPIWorks($url)
    {
        $accessToken = $this->getAccessToken();
        $tokenQuery = http_build_query(['access_token' => $accessToken]);
        $url .= '?' . $tokenQuery;
        $client = self::createClient([]);
        $client->request('GET', $url, [], [], ['HTTP_ACCEPT' => 'application/json']);

        $this->assertTrue($client->getResponse()->isSuccessful());
    }
0
votes
protected function setUp()
{
    $this->client = static::createClient();

    $this->logIn();
}

private function logIn()
{
    $session = $this->client->getContainer()->get('session');

    $firewallName = 'test';
    // if you don't define multiple connected firewalls, the context defaults to the firewall name
    // See https://symfony.com/doc/current/reference/configuration/security.html#firewall-context
    $firewallContext = 'test';

    // you may need to use a different token class depending on your application.
    // for example, when using Guard authentication you must instantiate PostAuthenticationGuardToken
    $testUser = new WebserviceUser('[email protected]', ['ROLE_ADMIN'],
        array("employeeid" => array(420),
        "mail" => array("[email protected]")), false);
    $token = new UsernamePasswordToken($testUser, null, $firewallName, ['ROLE_ADMIN']);
    //var_dump($token);
    $session->set('_security_' . $firewallContext, serialize($token));
    $session->save();

    $cookie = new Cookie($session->getName(), $session->getId());
    $this->client->getCookieJar()->set($cookie);
}


public function testCreate()
{

    $crawler = $this->client->request('GET', '/create');
    $this->assertEquals(200, $this->client->getResponse()->getStatusCode());

    $form = $crawler->filter('form')->form([
        'person[name]' => 'Chruit',
        'person[birthdate][month]' => 2,
        'person[birthdate][day]' => 15,
        'person[birthdate][year]' => 2014,
    ]);

    $this->client->submit($form);
}

public function testIndex()
{

    $this->client->request('GET', '/');

    $this->assertEquals(200, $this->client->getResponse()->getStatusCode());
}

}

The Solution is just the logIn-Function. The $testUser needs to be in your Active Directory or your network. The rest of the Parameters doesn't matter.

My Firewall blocked it so i couldn't do it the normal way.

If You are doing it like this, you have to add someting to the secourity.yaml that was created from the installation of PHPUnit.

enter image description here