在测试中模拟laravel环境

时间:2018-06-13 18:13:12

标签: php laravel mocking phpunit environment-variables

我实现了一些需要代码在生产环境中表现不同的逻辑。

我想写一个测试,断言这实际发生了,但我在嘲笑环境时遇到了困难。

seen it suggested使用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毫秒,内存:18.00MB

     

有1次失败:

     

1)EnvTest :: testEnv

     

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

     

---预计

     

+++ Actual

     

@@ @@

     

- '生产'

     

+'测试'

4 个答案:

答案 0 :(得分:3)

我知道这个问题已经一岁了,但是对于那些看起来像我一样的人来说,这在5.8中对我有用

const phone = ''; // same assumption like above

phone || doSomething(); // ==> yeah, that's right, the empty string is valid for us and the doSomething is not run

答案 1 :(得分:1)

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
    }

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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