Laravel 单元测试依赖注入

Posted

技术标签:

【中文标题】Laravel 单元测试依赖注入【英文标题】:Laravel Unit Testing Dependency Injection 【发布时间】:2017-04-01 03:29:12 【问题描述】:

我正在尝试为购物车编写一个测试类。这是我所拥有的:

ShoppingCartTest.php

class ShoppingCartTest extends TestCase 

    use DatabaseTransactions;

    protected $shoppingCart;

    public function __construct() 
        $this->shoppingCart = resolve('App\Classes\Billing\ShoppingCart');
    

    /** @test */
    public function a_product_can_be_added_to_and_retrieved_from_the_shopping_cart() 

        // just a placeholder at the moment
        $this->assertTrue(true);
    


但是,当我运行 phpunit 时,Laravel 似乎无法解析我的 ShoppingCartClass。

这是错误:

Fatal error: Uncaught exception 'Illuminate\Contracts\Container\BindingResolutionException'
with message 'Unresolvable dependency resolving
[Parameter #0 [ <required> $app ]] in class Illuminate\Support\Manager'
in C:\Development Server\EasyPHP-Devserver-16.1\eds-www\nrponline\vendor\laravel\framework\src\Illuminate\Container\Container.php:850

我的 ShoppingCart 类在许多不同的控制器中被解析得很好。

为什么 Laravel 在我的测试中不能解决它?

我也参考了this post,但仍然没有任何运气。

【问题讨论】:

你能发布App\Classes\Billing\ShoppingCart的构造函数吗? @edcs 当然可以。这是课程。 pastebin.com/bPRpmtnH 酷 - 谢谢!你可以尝试使用$this-&gt;app-&gt;make('App\Classes\Billing\ShoppingCart');,因为所有 Laravel 测试都有一个可用的应用程序实例作为属性。 @edcs 感谢您的回复。我尝试了$this-&gt;app-&gt;make('App\Classes\Billing\ShoppingCart'),现在出现了一个新错误。 致命错误:在 null 上调用成员函数 make() 只看我自己的一个项目,我从不使用__construct() 来创建事物的实例。尝试将 __construct() 重命名为 setupShoppingCart()(或类似名称 - 名称无关紧要)并创建一个包含 @before 的文档块,如下所示: /** * @before */ 【参考方案1】:

我想通了。这是更新后的课程。

class ShoppingCartTest extends TestCase 

    use DatabaseTransactions;

    protected $shoppingCart;

    public function setUp() 

        parent::setUp();

        $this->shoppingCart = $this->app->make('App\Classes\Billing\ShoppingCart');
    

    /** @test */
    public function a_product_can_be_added_to_and_retrieved_from_the_shopping_cart() 

        // just a placeholder at the moment
        $this->assertTrue(true);
    


感谢@edcs 为我指引正确的方向。 您需要使用 setUp 函数而不是 __construct,因为尚未创建 app 实例。

【讨论】:

如果你只想像__construct() 那样只执行一次代码,你应该使用setUpBeforeClass()【参考方案2】:

如果你想使用__construct,你必须使用与PHPUnit\Framework\TestCase相同的构造函数,如果你不想破坏任何东西,记得调用父方法

class MyTest extends TestCase

    public function __construct($name = null, array $data = [], $dataName = '')
    
        parent::__construct($name, $data, $dataName);

        // my init code
    

但是正确的方法是使用方法setUpBeforeClass(),如果你想执行一次你的初始化代码,或者setUp(),如果你想在你的类中包含的每个测试之前执行初始化代码。 详情请查看PHPUnit documentation。

【讨论】:

以上是关于Laravel 单元测试依赖注入的主要内容,如果未能解决你的问题,请参考以下文章

nestjs 单元测试 createTestingModule 依赖注入

如何在单元测试中从依赖注入容器中获取实例?

依赖注入和单元测试

如何调整我的视图模型以实现依赖注入 swiftui(用于以后的单元测试)

Kotlin Spring Boot 单元测试 - 添加 @TestExecutionListeners 不会注入依赖项

如何使用构造函数依赖注入对 asp.net 核心应用程序进行单元测试