1

I am about $this->close() to giving up on Mockery in my unit tests. Here's what's going on, I am working with Laravel 5.1 and I'm trying to test my repository pattern abstraction using Mockery in PHPUnit. I've followed the tutorials, poured over the StackOverflow questions so it's not a duplicate. When you see anything about modules here, it's PingPong Sky Modules package.

Basically, when I try to mock the repository interface and set shouldReceive('create')->with([])->once() , Mockery throws:

Mockery\Exception\InvalidCountException: Method create(array()) from Mockery_0_Modules_Documents_Repositories_DocumentRepositoryInterface should be called exactly 1 times but called 0 times.

DocumentsTest.php

<?php

use Illuminate\Foundation\Testing\WithoutMiddleware;

class FileUploadTest extends TestCase {

    use WithoutMiddleware;

    public function mock($class){

        $mock = Mockery::mock($class);

        $this->app->instance($class, $mock);

        return $mock;
    }

    public function testFileUpload(){

        // Mock the Repository
        $mock = $this->mock('\Modules\Documents\Repositories\DocumentRepositoryInterface');

        $mock->shouldReceive('create')->with([])->once();

        $this->call('POST', '/documents', [], [], []);
        $this->assertResponseStatus(201);
    }
}

DocumentRepositoryInterface.php

<?php namespace Modules\Documents\Repositories;

interface DocumentRepositoryInterface {

    public function create(array $data);

}

DatabaseDocumentRepository.php

<?php namespace Modules\Documents\Repositories;

use Modules\Documents\Repositories\DocumentRepositoryInterface;
use \Illuminate\Database\Eloquent\Model;

class DatabaseDocumentRepository implements DocumentRepositoryInterface {

    protected $documents;

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

    public function create(array $data) {
        // Eloquent code.
        return "response";
    }

}

Document.php

<?php namespace Modules\Documents\Entities;

use Illuminate\Database\Eloquent\Model;

class Document extends Model {

    protected $fillable = [];

}

routes.php

$this->app->bind(
        'Modules\Documents\Repositories\DocumentRepositoryInterface', function(){ 
    return new Modules\Documents\Repositories\DatabaseDocumentRepository(new Modules\Documents\Entities\Document());
});

Route::group(['prefix' => 'documents', 'namespace' => 'Modules\Documents\Http\Controllers'], function(){
    Route::post('/', ['as' => '/', 'uses'=> 'DocumentsController@create']);
});

DocumentsController.php

<?php namespace Modules\Documents\Http\Controllers;

use Modules\Documents\Repositories\DocumentRepositoryInterface;
use Pingpong\Modules\Routing\Controller;
use Module;
use Illuminate\Http\Response;
use Illuminate\Http\Request;

class DocumentsController extends Controller {
    private $documents;

    public function __construct(DocumentRepositoryInterface $doc){

        $this->documents = $doc;
    }

    public function create(Request $request){
        $this->documents->create([]);

        return response("", Response::HTTP_CREATED);
    }
}

I want to say it has something to do with the mocked object not getting injected into the DocumentsController because the create() function is getting called. I put a print_r in the create function and it displayed in my console. This is strange and it could also be related to PingPong Sky Modules. What am I doing wrong or not doing?

SacWebDeveloper
  • 2,563
  • 2
  • 18
  • 15

0 Answers0