php - Symfony 5 Api 测试 createClient() LogicalException

标签 php symfony testing phpunit symfony5

正如标题所说,我正在使用 Symfony 5 构建一个 API。我有一些 Controller 需要不同的用户权限,我想测试它们,所以我决定创建两个具有不同角色的用户用于测试目的 - ROLE_USERROLE_ADMIN。 当前代码是这样的(注意,它不是完整的代码,只是一个虚拟示例/起点)

ApiTestCase.php

<?php

namespace App\Tests;

use App\Entity\User;
use App\Tests\Http\RequestBuilder;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class ApiTestCase extends WebTestCase
{

    private static $userData = [
        'firstName' => 'Pera',
        'lastName'  => 'Peric',
        'email'     => 'test.user@test.com',
        'password'  => 'test123',
        'roles'     => [
            'ROLE_USER'
        ]
    ];

    private static $adminUserData = [
        'firstName' => 'Admin',
        'lastName'  => 'Adminovic',
        'email'     => 'admin.user@test.com',
        'password'  => 'admin123',
        'roles'     => [
            'ROLE_ADMIN'
        ]
    ];

    public static function createTestUser()
    {
        $res = RequestBuilder::create(self::createClient())
            ->setMethod('POST')
            ->setUri('/api/v1/security/register')
            ->setJsonContent(self::$userData)
            ->getResponse();

        $data = $res->getJsonContent();
        return $data['data'];
    }

    public static function createTestAdminUser()
    {
        $res = RequestBuilder::create(self::createClient())
            ->setMethod('POST')
            ->setUri('/api/v1/security/register')
            ->setJsonContent(self::$adminUserData)
            ->getResponse();

        $data = $res->getJsonContent();
        var_dump($data);
        return $data['data'];
    }

    public static function deleteTestUser()
    {
        self::createClient()->getContainer()
            ->get('doctrine.orm.entity_manager')
            ->getRepository(User::class)
            ->deleteUserByEmail(self::$userData['email']);
    }

    public static function deleteTestAdminUser()
    {
        self::createClient()->getContainer()
            ->get('doctrine.orm.entity_manager')
            ->getRepository(User::class)
            ->deleteUserByEmail(self::$adminUserData['email']);
    }

}

LocationControllerTest.php


namespace App\Tests;

use PHPUnit\Framework\TestCase;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class LocationControllerTest extends ApiTestCase
{
    public static $user;
    public static $adminUser;

    public static function setUpBeforeClass()
    {
        self::$user = self::createTestUser();
        self::$adminUser = self::createTestAdminUser();
    }

    public function testUsersExist()
    {
        // this is jut to test out an idea
        $this->assertContains('ROLE_USER', self::$user['roles']);
        $this->assertContains('ROLE_ADMIN', self::$adminUser['roles']);
    }

    public static function tearDownAfterClass()
    {
        self::deleteTestUser();
        self::deleteTestAdminUser();
    }
}

当我运行测试时(sunit 是别名 php bin/phpunit):

➜  skeleton master ✗ (*?) sunit --filter LocationController                                                                                                              [10:12AM]
PHPUnit 7.5.17 by Sebastian Bergmann and contributors.

Testing Project Test Suite
E                                                                   1 / 1 (100%)

Time: 742 ms, Memory: 24.00 MB

There was 1 error:

1) App\Tests\LocationControllerTest::testUsersExist
LogicException: Booting the kernel before calling Symfony\Bundle\FrameworkBundle\Test\WebTestCase::createClient() is not supported, the kernel should only be booted once. in /Users/shkabo/code/skeleton/vendor/symfony/framework-bundle/Test/WebTestCase.php:44
Stack trace:
#0 /Users/shkabo/code/skeleton/tests/ApiTestCase.php(45): Symfony\Bundle\FrameworkBundle\Test\WebTestCase::createClient()
#1 /Users/shkabo/code/skeleton/tests/LocationControllerTest.php(16): App\Tests\ApiTestCase::createTestAdminUser()
#2 /Users/shkabo/code/skeleton/bin/.phpunit/phpunit-7.5-0/src/Framework/TestSuite.php(703): App\Tests\LocationControllerTest::setUpBeforeClass()
#3 /Users/shkabo/code/skeleton/bin/.phpunit/phpunit-7.5-0/src/Framework/TestSuite.php(746): PHPUnit\Framework\TestSuite->run(Object(PHPUnit\Framework\TestResult))
#4 /Users/shkabo/code/skeleton/bin/.phpunit/phpunit-7.5-0/src/TextUI/TestRunner.php(652): PHPUnit\Framework\TestSuite->run(Object(PHPUnit\Framework\TestResult))
#5 /Users/shkabo/code/skeleton/bin/.phpunit/phpunit-7.5-0/src/TextUI/Command.php(206): PHPUnit\TextUI\TestRunner->doRun(Object(PHPUnit\Framework\TestSuite), Array, true)
#6 /Users/shkabo/code/skeleton/bin/.phpunit/phpunit-7.5-0/src/TextUI/Command.php(162): PHPUnit\TextUI\Command->run(Array, true)
#7 /Users/shkabo/code/skeleton/bin/.phpunit/phpunit-7.5-0/phpunit(17): PHPUnit\TextUI\Command::main()
#8 /Users/shkabo/code/skeleton/vendor/symfony/phpunit-bridge/bin/simple-phpunit.php(291): include('/Users/shkabo/c...')
#9 /Users/shkabo/code/skeleton/bin/phpunit(13): require('/Users/shkabo/c...')
#10 {main}
ERRORS!
Tests: 1, Assertions: 0, Errors: 1.

我理解这个错误,但似乎无法找到它/这种方法的解决方案。此外,我很可能以错误的方式进行操作。

在数据库中,第一个用户被创建,而第二个用户在我尝试创建它时抛出此错误。

我想要实现的是我拥有(静态)方法,我可以调用这些方法并创建虚拟用户/位置/等。并在测试该特定 Controller 时使用它,并在完成该特定 Controller 的测试后将其从数据库中销毁/删除。

RequestBuilder https://github.com/nebkam/fluent-test/blob/master/src/RequestBuilder.php

最佳答案

根据官方建议,您可以在创建客户端之前调用 self::ensureKernelShutdown()

self::ensureKernelShutdown();
$sally = static::createClient();

我不确定这是否是解决这个问题的方法,但我遇到了类似的问题,Google 将我带到了这里。

https://github.com/symfony/symfony-docs/issues/12961

关于php - Symfony 5 Api 测试 createClient() LogicalException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59389497/

相关文章:

php - 多种形式包括symfony(同一页面)

php - Symfony2 中组序列验证器的问题

android - 测试多种屏幕分辨率

c# - Windows Phone 7 测试的最佳模拟库

php - 当我尝试在 php 中将套接字绑定(bind)到本地主机时获取 'Address already in use'

php - tidy_repair_string 删除结束换行符(\n 或\r)

php - 在 SQL 中计算级联价格规则

php - Symfony 3 SessionHandler 警告

php - 我无法让 rewieer/TaskSchedulerBundle for Symfony 工作

java - "Invalid use of argument matchers"但我只使用匹配器