mjlovefl's avatar

How to test a $model->create(); failure.

I am stumped on how to test a failure in a create() method. Given a function like:

  /**
     * Add an item.
     *
     * @param string $name
     *
     * @return \App\Item|null
     */
    private function addItem( $name )
    {

        $item = $item->create([
            'name' => $name,
        ]);

        if ( ! $item ){
            return false;
        }

        return true;

    } 

How would I test for false? I need create to fail (simulating a DB error perhaps).

0 likes
3 replies
mjlovefl's avatar

I am pretty sure Mocking is the way to go here. But I am using Reflection to access the method. The mock object nevers seems to be called.

skliche's avatar

@mikepmtl You could use an invalid database configuration if you want to simulate database failure:

// replace mysql_testing with the name of the database connection used in your tests
config(['database.connections.mysql_testing.database' => 'invalid']);
\DB::purge('mysql_testing');

// call addItem()

The call to create() should now throw an exception.

I have no idea if there is any condition where create() returns something like null or false. I can only think of situations throwing exceptions.

mjlovefl's avatar
mjlovefl
OP
Best Answer
Level 4

Thanks @skliche.

I actually found the solution I was looking for after a lot of Googling. I will post it here in case anyone ever searches it.

I am actually using a repository patterns with my models and calling the repository class, but it should work for any class, including Eloquent.

I think the issue is that I am instantiating my repository class using

app( ItemsRepository::class );

So the mock was never being called.

The key to getting Mocking to work for me was adding this line:

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

As in:

        $mock = \Mockery::mock( ItemsRepository::class );
        $mock->shouldReceive('create')->withAnyArgs()->andReturn( null )->once();
        $this->app->instance( ItemsRepository::class, $mock );

Once I registered the class with the mock, all worked as expected.

Please or to participate in this conversation.