我正在实现一些逻辑,要求代码在生产环境中表现不同。
我想编写一个测试来断言这确实发生,但我很难模拟环境。
我已经看到它建议使用
putenv('APP_ENV=production');
,但它似乎不起作用。
如何才能通过测试?
use Illuminate\Support\Facades\App;
use Tests\TestCase;
class EnvTest extends TestCase
{
public function testEnv()
{
// This assertion is fine
$env = App::environment();
$this->assertEquals('testing', $env);
putenv('APP_ENV=production');
// This assertion fails
$env = App::environment();
$this->assertEquals('production', $env);
}
}
时间:160 ms,内存:18.00MB
有 1 次失败:
1)EnvTest::testEnv
无法断言两个字符串相等。
--- 预计
+++实际
@@@@
-“生产”
+'测试'
我知道这个问题已经有一年了,但对于那些和我一样的人来说,这在 5.8 中对我有用
public function test_config_env()
{
$this->app->detectEnvironment(function() {
return 'production';
});
$this->assertEquals('production', app()->environment()); // pass
}
use App;
//...
public function my_awesome_test()
{
// Number of times method environment() have to be invoked
$number_of_calls_to_method = 2
// Fake, that we have production environment
App::shouldReceive('environment')
->times($number_of_calls_to_method)
->andReturn('production');
// Make here whatever you want in Production environment
}
App::environment()
你似乎没有从配置文件中读取!
public function test_config_env()
{
$this->app['config']->set(['app.env' => 'production']);
$this->assertEquals('production', $this->app['config']->get('app.env')); // pass
$this->assertEquals('production', $this->app->environment()); // fail
}
public function test_env()
{
$this->app['env'] = 'production';
$this->assertEquals('production', config('app.env')); // fail
$this->assertEquals('production', $this->app['config']->get('app.env')); // fail
$this->assertEquals('production', $this->app['env']); // pass
$this->assertEquals('production', $this->app->environment()); // pass
}
在 Laravel v5.3 上测试
我改编了@staskrak的答案,因此模拟的行为与带或不带参数调用
App::environment()
完全相同。它也不会抛出类似的错误,例如Received Mockery_0_Illuminate_Foundation_Application::offsetGet(), but no expectations were specified
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\App;
protected function mockEnvironment(string $environment)
{
App::shouldReceive('environment')
->withAnyArgs()
->zeroOrMoreTimes()
->andReturnUsing(function ($args) use ($environment) {
// Return the current environment if no args are passed
if (!$args) {
return $environment;
}
// Wrap the args in an array if it's not in array yet
if (!is_array($args)) {
$args = Arr::wrap($args);
}
// Check if the current environment is in the given args
return in_array($environment, $args);
});
App::partialMock();
}
您可以使用
detectEnviroment
临时更改环境变量:
app()->environment('production') // False
app()->detectEnvironment(fn () => 'production');
app()->environment('production') // True