Learning Testing - Using Classes with dependency injection

Posted 1 year ago by longestdrive

Hi - my ongoing battle to learn testing in Laravel 5.5 continues.

I've created a class that extends a package to add functionality to it that counts certain items depending on different conditions

My thoughts in testing were to:

  1. set up and create the class
  2. populate a cart
  3. carry out my assertions

So - stumbling block number 1. The parent class of my class needs dependencies injected, which in turn has classed that need dependencies. Laravel normally takes care of this. I'm getting errors in setting up the class.

ArgumentCountError : Too few arguments to function Illuminate\Support\Manager::__construct(), 0 passed in /home/vagrant/code/golfmanager18/tests/Unit/CartTest.php on line 31 and exactly 1 expected

-Question 1. Am I approaching this in the right way - should I be doing something else?

-Question 2. How can I initiate a new class that has DI - it all feels very complicated at the moment

My class Cart I'm trying to build tests for:

namespace App\Golfmanager\Cart;

class Cart extends \Gloudemans\Shoppingcart\Cart
{
    public static function destroyCart($carts = array('greenfee', 'main', 'payment', 'resource'))
    {
        foreach ($carts as $strCartName) {
            Cart::instance($strCartName)->destroy();
        }
    }

    /**
     * @param string $cartName
     * @return int
     */
    public function getCartGroupSize($cartName = 'main')
    {
        $cart = $this->instance($cartName)->content();

        $groupSize = 0;

        foreach ($cart as $row) {

            if (in_array($row->options->type, array('Green Fee', 'Society Package'))) {
                $groupSize = $groupSize + $row->qty;
            }
        }

        return $groupSize;
    }

    /**
     * @param string $cartName
     * @return int
     */
    public function getCartCostsTotal($cartName = 'main')
    {
        $cart = $this->instance($cartName)->content();

        $costs = 0;

        foreach ($cart as $row) {
            $costs = $costs + $row->options->cost;
        }
        return $costs;

    }
}

The parent class - constructor only

    public function __construct(SessionManager $session, Dispatcher $events)
    {
        $this->session = $session;
        $this->events = $events;

        $this->instance(self::DEFAULT_INSTANCE);
    }

And finally my test:

class CartTest extends TestCase
{

    private $cart;

    public function setUp()
    {
        parent::setUp();

    }

    public function before()
    {
        $this->cart = new Cart(new SessionManager, new Dispatcher);
    }

    public function test_group_size_calculation()
    {

//        $this->cart = new Cart();

        dd($this->cart);
//        clear any existing cart entries
        $this->destroyCart('greenfee');

//        add 1st green fee product
        $options = $this->createAttributes();
        $this->addToCart(8, "test product", 1, 25, $options);

        $this->assertEquals($this->cart->getCartGroupSize('greenfee'), 1);

//        add non green fee product
        $options = $this->createAttributes(['type'=>'Something Else']);
        $this->addToCart(10, "test other product", 10, 25, $options);

        $this->assertEquals($this->cart->getCartGroupSize('greenfee'), 1);
    }

    private function createAttributes($attributes = [])
    {
        $base = [
            'cost'     => 10,
            'type'     => 'Green Fee',
            'mealQty'  => 1,
            'dateTime' => Carbon::now()
        ];

        return array_merge($base, $attributes);
    }

    private function addToCart($id, $name, $people, $salePerHead, $options)
    {
        $this->cart->add(
            $id,
            $name,
            $people,
            $salePerHead,
            $options
        );
    }

    private function destroyCart($string)
    {
        $this->cart->instance('greenfee')->destroy();
    }
}

All help appreciated to get me over this testing learning curve

Please sign in or create an account to participate in this conversation.