Ben Thompson
Ben Thompson

Reputation: 4833

How do I test this class using phpunit?

I am using Laravel 4.2 and am trying to get into using phpunit to test my code rather than manually test everything. I have read Jeffrey Way's book 'Laravel Testing Decoded' but I still finding my very first test tricky. The class I am trying to test is below. What I am struggling with is - what should I test?

I don't think I should test the database or the Model $advert as these should have their own tests. In which case I think I need to either mock $advert or create a factory for it but I don't know which.

Any pointers would be greatly appreciated.

EloquentListing.php

<?php

namespace PlaneSaleing\Repo\Listing;

use Illuminate\Database\Eloquent\Model;

class EloquentListing implements ListingInterface {

    protected $advert;

    public function __construct(Model $advert)
    {
        $this->advert = $advert;
    }

    /**
     * Get paginated listings
     *
     * @param int  Current page
     * @param int Number of listings per page
     * @return StdClass object with $items and $totalItems for pagination
     */
    public function byPage($page=1, $limit=10)
    {

        $result = new \StdClass;
        $result->page = $page;
        $result->limit = $limit;
        $result->totalItems = 0;
        $result->items = array();

        $listings = $this->advert
                         ->orderBy('created_at')
                         ->skip( $limit * ($page-1) )
                         ->take($limit)
                         ->get();

        // Create object to return data useful for pagination
        $result->items = $listings->all();
        $result->totalItems = $this->totalArticles;

        return data;

    }
    /**
     * Get total listing count
     *
     * 
     */
    protected function totalArticles()
    {

        return $this->advert->count();

    }

}

Upvotes: 3

Views: 912

Answers (1)

Vadims Auzans
Vadims Auzans

Reputation: 61

You have to test every method you have in your class. You have constructor, which should be also tested, to see, if it sets model to your attributes, as well your protected method.

You should mock your model with mockery. It can be installed with

$ composer require mockery/mockery

Then in your test file:

<?php

use Mockery;
use ReflectionClass;
use PlaneSaleing\Repo\Listing\EloquentListing;

class EloquentListingTest extends \TestCase
{

    /**
     * Testing if __constructor is setting up property
     */
    public function testModelSetsUp()
    {
        $mock = Mockery::mock(Illuminate\Database\Eloquent\Model::class);

        $listing = new EloquentListing($mock);

        $reflection = new ReflectionClass($listing);

        // Making your attribute accessible
        $property = $reflection->getProperty('advert');
        $property->setAccessible(true);

        $this->assertInstanceOf(Illuminate\Database\Eloquent\Model::class, $property);
    }

    /**
     * Here you will check if your model is recieving calls
     */
    public function testByPage()
    {
       $mock = Mockery::mock(Illuminate\Database\Eloquent\Model::class);

       $mock->shouldReceive('orderBy')
            ->with('created_at')
            ->once()
            ->andReturn(Mockery::self())
            ->shouldReceive('skip')
            ->with(10)
            ->once()
            ->andReturn(Mockery::self())
            ->shouldReceive('take')
            ->with(10)
            ->andReturn(Mockery::self())
            ->shouldReceive('get')
            ->once()
            ->andReturn(Mockery::self())
            ->shouldReceive('all')
            ->once()
            ->andReturn(Mockery::self());

        $listing = new EloquentListing($mock);
    }

    /**
     * Here you will see, if your model is receiving call '->count()'
     */
    public function testTotalArticles()
    {
        $mock = Mockery::mock(Illuminate\Database\Eloquent\Model::class);

        $mock->shouldReceive('count')
            ->once()
            ->andReturn(Mockery::self());

        $listing = new EloquentListing($mock);

        // We will have to set method accesible
        $reflection = new ReflectionClass($listing);

        $method = $reflection->getMethod('totalArticles');
        $method->setAccessible(true);

        $listing->totalArticles();
    }

}

Upvotes: 2

Related Questions