Laravel Unit Testing Abhängigkeitsinjektion

Lesezeit: 3 Minuten

Benutzeravatar von Denis Priebe
Denis Prieb

Ich versuche, eine Testklasse für einen Einkaufswagen zu schreiben. Hier ist, was ich habe:

WarenkorbTest.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);
    }

}

Wenn ich jedoch phpunit ausführe, scheint Laravel meine ShoppingCartClass nicht auflösen zu können.

Hier ist der Fehler:

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

Ich habe meine ShoppingCart-Klasse, die in einer Reihe verschiedener Controller problemlos aufgelöst wird.

Warum kann Laravel es während meiner Tests nicht lösen?

Ich habe auch auf diesen Beitrag verwiesen, aber immer noch kein Glück gehabt.

  • Könnten Sie den Konstruktor für posten App\Classes\Billing\ShoppingCart bitte?

    – edcs

    17. November 2016 um 16:39 Uhr

  • @edcs Sichere Sache. Hier ist die Klasse. pastebin.com/bPRpmtnH

    – Denis Priebe

    17. November 2016 um 16:44 Uhr

  • Cool, danke! Du könntest versuchen, es zu verwenden $this->app->make('App\Classes\Billing\ShoppingCart'); da alle Laravel-Tests eine Instanz der Anwendung als Eigenschaft zur Verfügung haben.

    – edcs

    17. November 2016 um 16:54 Uhr

  • @edcs Danke für die Antwort. Ich habe es mit versucht $this->app->make('App\Classes\Billing\ShoppingCart') und bekomme jetzt einen neuen Fehler. Schwerwiegender Fehler: Aufruf einer Member-Funktion make() bei null

    – Denis Priebe

    17. November 2016 um 17:07 Uhr


  • Wenn ich mir nur eines meiner eigenen Projekte anschaue, verwende ich es nie __construct() Instanzen von Dingen zu schaffen. Versuchen Sie es mit einer Umbenennung __construct() zu setupShoppingCart() (oder ähnlich – der Name spielt keine Rolle) und erstelle einen Docblock, der hat @before darin wie folgt: /** * @before */

    – edcs

    17. November 2016 um 17:12 Uhr

Benutzeravatar von Denis Priebe
Denis Prieb

Ich habe es herausgefunden. Hier ist die aktualisierte Klasse.

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);
    }

}

Danke an @edcs, dass du mich in die richtige Richtung geführt hast. Sie müssen eine Setup-Funktion verwenden und nicht __construct als die app Instanz wurde noch nicht erstellt.

  • Du solltest benutzen setUpBeforeClass() wenn Sie den Code nur einmal ausführen möchten __construct() normalerweise tut

    – Andrea Mauro

    10. Juli 2019 um 10:48 Uhr

Wenn Sie verwenden möchten __construct Sie müssen denselben Konstruktor von verwenden PHPUnit\Framework\TestCase und denken Sie daran, die übergeordnete Methode aufzurufen, wenn Sie nichts beschädigen möchten

class MyTest extends TestCase
{
    public function __construct($name = null, array $data = [], $dataName="")
    {
        parent::__construct($name, $data, $dataName);

        // my init code
    }
}

Der richtige Weg wäre jedoch, die Methode zu verwenden setUpBeforeClass() wenn Sie Ihren Init-Code einmal ausführen möchten oder setUp() wenn Sie den Init-Code vor jedem in Ihrer Klasse enthaltenen Test ausführen möchten. Prüfen PHPUnit-Dokumentation für mehr Details.

  • hatte ich anfangs __construct(...$args) { parent::__construct(...$args); ... } und es scheiterte bei Tests mit Datenanbietern. Das hat funktioniert.

    – s3c

    6. Oktober um 21:26 Uhr

1430430cookie-checkLaravel Unit Testing Abhängigkeitsinjektion

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy