简体   繁体   English

在单元测试时使用Laravel辅助函数

[英]Using Laravel helper functions when unit testing

I am testing a class I made that uses a helper function. 我正在测试一个使用辅助函数的类。 The function I'm testing looks like: 我正在测试的功能如下:

public function upload(UploadedFile $file)
{
    $file = $file->move(base_path() . '/temp');
    $file = new FileSystemPicture($file);

    return $file;
}

When I run the tests and it hits the helper function it says: 当我运行测试并且它命中辅助函数时,它说:

PHP Fatal error:  Call to a member function make() on a non-object

I have tracked the helper function down to be the following code: 我已经跟踪了辅助函数,它是以下代码:

function base_path($path = '')
{
    return app()->make('path.base').($path ? '/'.$path : $path);
}

I know that I'm getting the error because the "app" hasn't been created because I'm only testing the my class, not the whole application. 我知道我收到了错误,因为“app”尚未创建,因为我只测试了我的类,而不是整个应用程序。 Are there other effective ways to get the root directory of my project or is there a way to force the "app" to load so it can be used in this function? 是否有其他有效的方法来获取我的项目的根目录或有没有办法强制“app”加载,以便它可以在此功能中使用?

I had this problem, solved making sure that: 我有这个问题,解决了确保:

  1. My test class extended TestCase. 我的测试类扩展了TestCase。
  2. If my test class had a setUp() method, it called parent::setUp() 如果我的测试类有一个setUp()方法,则调用parent::setUp()

app_path() and similar functions worked after that. app_path()和类似的函数在那之后起作用。

There is a way to mock helper functions that use app() function in a complete isolation from laravel environment. 有一种方法可以模拟使用app()函数的辅助函数,与laravel环境完全隔离。 Considering that your package has illuminate/support dependency you could do something like this: 考虑到你的软件包具有illuminate/support依赖性,你可以这样做:

<?php

    class Test extends PHPUnit_Framework_TestCase
    {
        protected function mockApplication(array $methods = [])
        {
            return $this->getMock('Illuminate\Foundation\Application', $methods);
        }

        public function testHelperFunction()
        {
            $appMock = $this->mockApplication(['make']);

            \Illuminate\Support\Facades\Facade::setFacadeApplication($appMock);

            $testPath = "my/path";
            $myPath = "otherPath";

            $expectedValue = "{$testPath}/{$myPath}";

            $appMock->expects($this->once())
                    ->method('make')->with('path.base')
                    ->will($this->returnCallback(function () use ($testPath) {
                        return $testPath;
                    }));

            $this->assertSame($expectedValue, base_path($myPath));
        }

    }

I just ran into this issue, and my solution is to wrap the whole helpers.php contents with 我刚刚遇到这个问题,我的解决方案是将整个helpers.php内容包装起来

if (!file_exists('newFunction')) {

This should prevent the attempt at re-declaring the functions after the first test case has executed. 这应该可以防止在第一个测试用例执行后重新声明函数的尝试。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM