【问题标题】:setId is ignored for referenced DataFixtures Symfony4 / DoctrinesetId 对于引用的 DataFixtures Symfony4 / Doctrine 被忽略
【发布时间】:2019-03-12 21:09:38
【问题描述】:

我正在使用 DataFixtures 为我的测试数据库填充单元测试的数据。

对于不使用其他实体的实体,我可以使用 setId 设置主键。对于其他实体使用的实体,我可以设置它,但它会被忽略。

例如我正在这样设置我的用户:

    /** @var Gender $genderW */
    $genderM = $this->getReference(GenderFixtures::TEST_GENDER_W);

    $date = new DateTime('now');
    /** @var User $user */
    $user = new User();
    $user
        ->setId(9)
        ->setFirstName('Hermione')
        ->setLastName('Granger')
        ->setEmail('test9@example.com')
        ->setGender($genderM)
        ->setPassword('odsf3_!45sr-f')
        ->setCreated($date);

    $manager->persist($user);

    $manager->flush();

    $this->addReference(self::TEST_USER_REFERENCE_9, $user);

如您所见,我为 Hermione 设置了 ID,但如果我在测试中执行 var_dump,我会看到用户 ID 会随着我正在运行的每个测试的用户数量而增加。 (9, 18, 27....)

结果是,在我的测试中,我必须通过唯一的电子邮件地址来获取用户,这是可能的,但很烦人:

    $userRepo = $this->em->getRepository(User::class);
    $this->user = $userRepo->findOneBy(['email' => 'test9@example.com']);
    var_dump($this->user->getId());

是否有可能更改此设置,以便我可以通过 Id 获取我的用户?

配置:

"require": {
    "php": "7.2.*",
    "ext-ctype": "*",
    "ext-iconv": "*",
    "cache/predis-adapter": "^1.0",
    "doctrine/doctrine-bundle": "^1.6.10",
    "doctrine/doctrine-migrations-bundle": "^1.3",
    "doctrine/orm": "^2.5.11",
    "eightpoints/guzzle-bundle": "~7.3.1",
    "friendsofsymfony/rest-bundle": "^2.3",
    "guzzlehttp/guzzle": "^6.3",
    "jms/serializer-bundle": "^2.4",
    "predis/predis": "^1.1",
    "sensio/framework-extra-bundle": "^5.2",
    "snc/redis-bundle": "3.x-dev",
    "symfony/apache-pack": "^1.0",
    "symfony/console": "^4.1",
    "symfony/flex": "^1.0",
    "symfony/framework-bundle": "^4.1",
    "symfony/lts": "^4@dev",
    "symfony/monolog-bundle": "^3.1",
    "symfony/orm-pack": "^1.0",
    "symfony/polyfill-apcu": "^1.5",
    "symfony/security-bundle": "^4.0",
    "symfony/swiftmailer-bundle": "^3.2",
    "symfony/twig-bundle": "^4.1",
    "symfony/validator": "^4.1",
    "symfony/yaml": "^4.1"
},
"require-dev": {
    "diablomedia/phpunit-pretty-printer": "2.0.*",
    "doctrine/doctrine-fixtures-bundle": "^3.0",
    "friendsofphp/php-cs-fixer": "*",
    "phpmd/phpmd": "^2.6",
    "sensiolabs/security-checker": "^4.1",
    "squizlabs/php_codesniffer": "*",
    "symfony/dotenv": "^4.1",
    "symfony/maker-bundle": "^1.5",
    "symfony/phpunit-bridge": "^4.1",
    "symfony/var-dumper": "^4.1"
},

【问题讨论】:

    标签: doctrine-orm phpunit symfony4 fixtures


    【解决方案1】:

    正确的方法是在每个类/为您的测试套件中创建 setUptearDown 方法。 使用这些方法,您可以在每次运行时在数据库中创建/截断测试数据。

    根据Databasetesting 的 Phpunit 文档,安装程序将在运行测试之前清理

    PHPUnit 将对您指定的所有表执行 TRUNCATE 以将其状态重置为空。

    只有截断,不重置自动增量值。

    要清理您的数据库密钥,您应该使用 tearDown 进行测试以重置密钥

    ALTER TABLE 表名 AUTO_INCREMENT = 1

    这将在每次测试后重置自动增量值。


    要仅使用 symfony 来实现这一点,您可以创建一个命令来执行以下操作:

    1. 重置测试数据库./app/console doctrine:fixtures:load --purge-with-truncatefound this command on SO
    2. 创建夹具
    3. 执行您的测试运行

    您将有 1 个命令来仅使用 symfony 运行测试。

    【讨论】:

    • 你会如何设置它?我们正在使用教义。我已经给了 $this->em->getConnection()->beginTransaction();和 $this->em->getConnection()->rollback();试一试,没有想要的结果。我不会完全想规避教义来完成这项工作。
    • 根据我的阅读,我认为问题不在于 phpunit 本身。一种可能的解决方案是自己编写一个 bash 脚本(如果在 linux 上)来加载夹具、运行测试并在测试完成后截断数据库。
    • 我正在使用 Doctrine\Bundle\FixturesBundle\Fixture ,所以理想情况下我想要一个解决方案,它不会规避 Doctrine Fixture Bundle 我的坏事......我在问题中添加了它跨度>
    • 我的想法是编写一个 shell 脚本来截断数据库、加载固定装置并运行测试。
    • 感谢您的提问!不太远。我想避免使用 bash 脚本,而是依赖内部工具。如果甚至可以像这样解决它,bash 脚本将是我最后的手段。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2022-11-02
    • 2010-10-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-12-03
    • 1970-01-01
    相关资源
    最近更新 更多