Explorar el Código

fix(test): 强制测试连独立的 mint_test 库,避免 RefreshDatabase 清空开发库

visuddhinanda hace 1 día
padre
commit
8f515a6ff2
Se han modificado 2 ficheros con 58 adiciones y 15 borrados
  1. 20 14
      api-v13/phpunit.xml
  2. 38 1
      api-v13/tests/TestCase.php

+ 20 - 14
api-v13/phpunit.xml

@@ -17,25 +17,31 @@
             <directory>app</directory>
         </include>
     </source>
+    <!--
+        每个 env 都必须带 force="true":php artisan test 会先 bootstrap Laravel 加载 .env,
+        此时 .env 的值已被 putenv 到真实环境。PHPUnit 12 的 <env> 默认 force=false,
+        遇到已存在的环境变量会跳过,导致这里的值全部被 .env 抢占(测试实际连到了
+        开发库 wikipali 而非 mint_test)。
+    -->
     <php>
-        <env name="APP_ENV" value="testing"/>
-        <env name="APP_MAINTENANCE_DRIVER" value="file"/>
-        <env name="BCRYPT_ROUNDS" value="4"/>
-        <env name="BROADCAST_CONNECTION" value="null"/>
-        <env name="CACHE_STORE" value="array"/>
+        <env name="APP_ENV" value="testing" force="true"/>
+        <env name="APP_MAINTENANCE_DRIVER" value="file" force="true"/>
+        <env name="BCRYPT_ROUNDS" value="4" force="true"/>
+        <env name="BROADCAST_CONNECTION" value="null" force="true"/>
+        <env name="CACHE_STORE" value="array" force="true"/>
         <!--
             迁移文件含 Postgres 专有语句(CREATE EXTENSION "uuid-ossp" 等),无法在 sqlite 上跑,
             故测试也走 pgsql。DB_DATABASE 必须固定为独立的测试库:RefreshDatabase 会清空目标库,
             指向开发库会直接毁掉数据。
         -->
-        <env name="DB_CONNECTION" value="pgsql"/>
-        <env name="DB_DATABASE" value="mint_test"/>
-        <env name="DB_URL" value=""/>
-        <env name="MAIL_MAILER" value="array"/>
-        <env name="QUEUE_CONNECTION" value="sync"/>
-        <env name="SESSION_DRIVER" value="array"/>
-        <env name="PULSE_ENABLED" value="false"/>
-        <env name="TELESCOPE_ENABLED" value="false"/>
-        <env name="NIGHTWATCH_ENABLED" value="false"/>
+        <env name="DB_CONNECTION" value="pgsql" force="true"/>
+        <env name="DB_DATABASE" value="mint_test" force="true"/>
+        <env name="DB_URL" value="" force="true"/>
+        <env name="MAIL_MAILER" value="array" force="true"/>
+        <env name="QUEUE_CONNECTION" value="sync" force="true"/>
+        <env name="SESSION_DRIVER" value="array" force="true"/>
+        <env name="PULSE_ENABLED" value="false" force="true"/>
+        <env name="TELESCOPE_ENABLED" value="false" force="true"/>
+        <env name="NIGHTWATCH_ENABLED" value="false" force="true"/>
     </php>
 </phpunit>

+ 38 - 1
api-v13/tests/TestCase.php

@@ -6,5 +6,42 @@ use Illuminate\Foundation\Testing\TestCase as BaseTestCase;
 
 abstract class TestCase extends BaseTestCase
 {
-    //
+    /**
+     * 测试环境变量:与 phpunit.xml 的 <env> 保持一致。
+     *
+     * 必须在这里(Laravel bootstrap 之前)把这些值同时写入 putenv / $_ENV / $_SERVER。
+     * 原因:Laravel 的 Env::get() 通过 Dotenv 的多 adapter 仓库读取,优先级是
+     * $_SERVER > $_ENV > getenv;而 PHPUnit 的 <env> 只写 putenv 与 $_ENV、不写 $_SERVER,
+     * 导致 .env 里的 DB_DATABASE(wikipali)在 $_SERVER 里胜出,测试会连到开发库,
+     * RefreshDatabase 的 migrate:fresh 会直接清空开发库数据。
+     *
+     * @var array<string, string>
+     */
+    private const TEST_ENV = [
+        'APP_ENV' => 'testing',
+        'APP_MAINTENANCE_DRIVER' => 'file',
+        'BCRYPT_ROUNDS' => '4',
+        'BROADCAST_CONNECTION' => 'null',
+        'CACHE_STORE' => 'array',
+        'DB_CONNECTION' => 'pgsql',
+        'DB_DATABASE' => 'mint_test',
+        'DB_URL' => '',
+        'MAIL_MAILER' => 'array',
+        'QUEUE_CONNECTION' => 'sync',
+        'SESSION_DRIVER' => 'array',
+        'PULSE_ENABLED' => 'false',
+        'TELESCOPE_ENABLED' => 'false',
+        'NIGHTWATCH_ENABLED' => 'false',
+    ];
+
+    public function createApplication()
+    {
+        foreach (self::TEST_ENV as $key => $value) {
+            putenv("{$key}={$value}");
+            $_ENV[$key] = $value;
+            $_SERVER[$key] = $value;
+        }
+
+        return parent::createApplication();
+    }
 }