如何在运行时更改应用环境?单元测试APP_ENV修改问题
修改Laravel单元测试中的APP_ENV环境变量
我完全懂你的困扰——想在单元测试里验证生产环境专属的服务绑定,但不管怎么用config(['app.env' => 'production']),app()->environment()始终顽固地返回testing,这确实让人头疼。
问题出在这:Laravel的应用环境是在应用启动阶段就确定并存在Application实例的私有属性里了,后续修改config只会更新配置数组,根本不会同步到Application实例已经缓存好的环境值上。
下面给你两种实用的解决办法,按需选就行:
方法一:临时切换单个测试方法的环境(灵活)
如果只是某几个测试需要验证生产环境的绑定,可以用PHP反射直接修改Application实例的环境属性:
public function test_production_services_are_bound() { // 获取当前应用实例 $app = app(); // 通过反射访问受保护的environment属性 $reflection = new ReflectionClass($app); $envProperty = $reflection->getProperty('environment'); $envProperty->setAccessible(true); // 把环境切换为production $envProperty->setValue($app, 'production'); // 现在可以断言你的生产环境服务是否正确绑定了 $this->assertInstanceOf(ProductionOnlyService::class, app(ProductionOnlyService::class)); // 测试结束后可以手动切回testing,或者依赖tearDown的resetApplication自动重置 $envProperty->setValue($app, 'testing'); }
运行这段代码后,再执行dump(app()->environment())就会输出production了。
方法二:让整个测试类都用production环境
如果你的测试类里所有方法都需要在生产环境下运行,可以重写测试类的createApplication方法,在应用启动前就设置好环境变量:
protected function createApplication() { // 先设置环境变量 putenv('APP_ENV=production'); // 加载并初始化应用 $app = require __DIR__.'/../bootstrap/app.php'; $app->make(Illuminate\Contracts\Console\Kernel::class)->bootstrap(); return $app; }
这样整个测试类的应用环境都会是production,不用在每个方法里重复操作。
你之前尝试的无效代码:
dump(app()->environment()); // "testing" config(['app.env' => 'production']); dump(app()->environment()); // "testing"
内容的提问来源于stack exchange,提问作者Jeff Puckett
相关产品推荐
相关产品推荐

