测试中模拟laravel环境

问题描述 投票:0回答:5

我正在实现一些逻辑,要求代码在生产环境中表现不同。

我想编写一个测试来断言这确实发生,但我很难模拟环境。

我已经看到它建议使用

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

无法断言两个字符串相等。

--- 预计

+++实际

@@@@

-“生产”

+'测试'

php laravel mocking phpunit environment-variables
5个回答
12
投票

我知道这个问题已经有一年了,但对于那些和我一样的人来说,这在 5.8 中对我有用

  public function test_config_env()
  {
    $this->app->detectEnvironment(function() {
      return 'production';
    });
    $this->assertEquals('production', app()->environment()); // pass
  }

5
投票
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
}

4
投票

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 上测试


2
投票

我改编了@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();
}

0
投票

您可以使用

detectEnviroment
临时更改环境变量:

app()->environment('production') // False

app()->detectEnvironment(fn () => 'production');

app()->environment('production') // True

© www.soinside.com 2019 - 2024. All rights reserved.