Php 当我';我在叫路线?

Php 当我';我在叫路线?,php,laravel-4,laravel-5,mockery,lumen,Php,Laravel 4,Laravel 5,Mockery,Lumen,我试图通过调用$this->call(“GET”、$route$data)来测试Lumen中的控制器方法。这将调用我的控制器类上的getUserList方法 但是我遇到了一个问题,因为getUserList方法调用了我需要模拟的控制器类上的一些方法。我试图为控制器类设置一个部分模拟,如下所示: $controller = Mockery::mock("App\Http\Controllers\MyController[myMethod]"); App::instance("App\Http\Co

我试图通过调用
$this->call(“GET”、$route$data)
来测试Lumen中的控制器方法。这将调用我的控制器类上的
getUserList
方法

但是我遇到了一个问题,因为
getUserList
方法调用了我需要模拟的控制器类上的一些方法。我试图为控制器类设置一个部分模拟,如下所示:

$controller = Mockery::mock("App\Http\Controllers\MyController[myMethod]");
App::instance("App\Http\Controllers\MyController", $controller);
class ControllerTest extends TestCase {
    public function test_1()
    {
        // set some stuff up

        // mock the controller
        $controller = Mockery::mock("App\Http\Controllers\MyController[myMethod]");
        App::instance("App\Http\Controllers\MyController", $controller);

        // call the method
        $result = $this->call("GET", $route, $data);    

        // assert some stuff
    }

    public function test_2()
    {
        // set some stuff up

        // mock the controller
        $controller = Mockery::mock("App\Http\Controllers\MyController[myMethod]");
        App::instance("App\Http\Controllers\MyController", $controller);

        // call the method
        $result = $this->call("GET", $route, $data);    

        // assert some stuff
    }
}
在每次测试中

我的测试如下所示:

$controller = Mockery::mock("App\Http\Controllers\MyController[myMethod]");
App::instance("App\Http\Controllers\MyController", $controller);
class ControllerTest extends TestCase {
    public function test_1()
    {
        // set some stuff up

        // mock the controller
        $controller = Mockery::mock("App\Http\Controllers\MyController[myMethod]");
        App::instance("App\Http\Controllers\MyController", $controller);

        // call the method
        $result = $this->call("GET", $route, $data);    

        // assert some stuff
    }

    public function test_2()
    {
        // set some stuff up

        // mock the controller
        $controller = Mockery::mock("App\Http\Controllers\MyController[myMethod]");
        App::instance("App\Http\Controllers\MyController", $controller);

        // call the method
        $result = $this->call("GET", $route, $data);    

        // assert some stuff
    }
}
这对于第一个测试很好,但是对于第二个和以后的测试,我声明的实例被遗忘了

我尝试了很多不同的方法:

  • 在每个测试中创建(或重新创建)模拟类

  • 创建模拟类的单个实例作为测试类的属性(在构造函数或
    setUp
    方法中初始化它)——这里的希望是为每个测试使用单个实例可以解决问题

  • 将测试中的
    call()
    方法更改为
    action()
    方法(即直接调用控制器方法,而不是通过对路由的HTTP请求)

  • 但这些方法都不起作用


    我可以重写代码,以便将需要模拟的代码移动到单独的库类中,然后对其进行模拟和使用,但这增加了一层复杂性。我正在尝试编写一个与特定遗留应用程序数据库接口的微服务-它只需要做少量的事情,所以我不想在这里添加大量代码。

    为什么要模拟控制器?您不应该模拟控制器-没有必要…我正在测试一个控制器方法,它调用另一个需要模拟的方法(访问一些在测试期间不应该访问的资源)。正如我在问题中所解释的,我并不真的想向这个应用程序添加额外的类——我希望它小而简单。我不太关心我的MVC架构的“纯洁性”,而是让团队中的其他人能够简单地理解和维护。你有控制器方法调用其他控制器方法吗?你也不应该这样做。这就是为什么您在测试中遇到麻烦的原因。您应该将逻辑提取到简单的命令中,并从控制器调用这些命令。更容易测试。而且这与MVC的“纯洁性”无关——它与编写良好的可测试可维护代码有关。从控制器内部调用控制器并非如此——因此不可正确测试……我确实理解这种方法对于可测试性的重要性——我为我所处理的应用程序这样做。在这种情况下,我正在组装一个微服务。查询遗留数据库有三种方法,我正在努力使事情尽可能简单。有许多辅助方法与控制器操作相关,因此我将它们放在控制器中。我可以把他们转移到一个单独的班级,但我觉得这比我想的要复杂得多。