如何测试 Laravel 5 控制器方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/29781103/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-14 11:24:50  来源:igfitidea点击:

How to test Laravel 5 controllers methods

phplaravelphpunitlaravel-5

提问by errogaht

We have Laravel 5 controllers method:

我们有 Laravel 5 控制器方法:

public function getInput()
{
    $input = \Request::all();
    $links = $input['links'];
    $this->startLinks =  explode("\n", $links);
    return $this;
}

How can we test this single method? How to pass POST request with data to this method? And how to create instance of this controller class in my test method?

我们如何测试这种单一方法?如何将带有数据的 POST 请求传递给此方法?以及如何在我的测试方法中创建这个控制器类的实例?

回答by user1669496

This looks like a method which probably shouldn't belong in a controller. If you are serious about testing, I'd highly recommend reading up on the repository pattern. When testing, it will make your life a lot easier to have everything abstracted out of the controllers.=

这看起来像是一个可能不应该属于控制器的方法。如果您认真对待测试,我强烈建议您阅读存储库模式。在测试时,从控制器中抽象出所有东西会让你的生活更轻松。=

With that said though, this is still very testable. The main idea is to figure out what needs to be tested and ONLY test that. This means we don't care what the dependencies are doing, only that they are doing and returning something which the rest of the method will need. In this case, it's the Requestfacade.

尽管如此,这仍然是非常可测试的。主要思想是找出需要测试的内容,并且仅对其进行测试。这意味着我们不关心依赖项在做什么,只关心它们正在做什么并返回方法的其余部分需要的东西。在这种情况下,它是Request外观。

Then you want to make sure the variables are set appropriately and that the method returned an instance of that class. It actually ends up being pretty straight forward.

然后,您要确保正确设置了变量,并且该方法返回了该类的实例。它实际上最终变得非常简单。

Should look something like this...

应该看起来像这样......

public function testGetInput()
{
    $requestParams = [
        'links' => "somelink.com\nsomeotherlink.com\nandanotherlink.com\ndoesntmatter.com"
    ];

    // Here we are saying the \Request facade should expect the all method to be called and that all method should
    // return some pre-defined things which we will use in our asserts.
    \Request::shouldReceive('all')->once()->andReturn($requestParams);

    // Here we are just using Laravel's IoC container to instantiate your controller.  Change YourController to whatever
    // your controller is named
    $class = App::make('YourController');

    // Getting results of function so we can test that it has some properties which were supposed to have been set.
    $return = $class->getInput();

    // Again change this to the actual name of your controller.
    $this->assertInstanceOf('YourController', $return);

    // Now test all the things.
    $this->assertTrue(isset($return->startLinks));
    $this->assertTrue(is_array($return->startLinks));
    $this->assertTrue(in_array('somelink.com', $return->startLInks));
    $this->assertTrue(in_array('nsomeotherlink.com', $return->startLInks));
    $this->assertTrue(in_array('nandanotherlink.com', $return->startLInks));
    $this->assertTrue(in_array('ndoesntmatter.com', $return->startLInks));
}

回答by Daniel Antos

I think you are looking for this.

我想你正在寻找这个

If your test class extends TestCaseyou will get a lot of helper methods which will do heavy lifting for you.

如果您的测试类扩展,TestCase您将获得许多辅助方法,这些方法将为您带来繁重的工作。

function testSomething() {
    // POST request to your controller@action
    $response = $this->action('POST', 'YourController@yourAction', ['links' => 'link1 \n link2']);
    // you can check if response was ok
    $this->assertTrue($response->isOk(), "Custom message if something went wrong");
    // or if view received variable
    $this->assertViewHas('links', ['link1', 'link2']);
}

Codeceptionextends this functionality even further.

Codeception进一步扩展了这个功能。