jeudi 2 juillet 2015

Laravel 5 Cannot Mock View

I'm trying to write a really basic test for one of my controllers

/**
 * THIS IS MY CONTROLLER. $this->badge is a repository
 * @return \Illuminate\Http\Response
 */
public function index()
{        
    return view('badges.index')->with([
       'badges' => $badges = $this->badge->all()
    ]);
}

I'm using repositories which return Eloquent collections. My basic test is as follows:

public function testItShowsAllBadges()
{
    // Arrange
    //DISABLE AUTH MIDDLEWARE ON THIS ROUTE
    $this->withoutMiddleware(); 
    // MOCK THE REPO
    $this->badge->shouldReceive('all')->andReturn(new Illuminate\Support\Collection);   

    // Act
    $response = $this->action('GET', 'BadgeController@index');

    // Assert
    $this->assertResponseOk();
    $this->assertInstanceOf('Illuminate\Support\Collection', $response->original->getData()['badges']);
    $this->assertViewHas('badges');
}

This test fails with a message 'trying to get property of non-object'. This is because I do Auth::user()->something in the view.

So I need to mock the view but I don't know how. Can someone advise?

Other SO answers do not seem to work and just result in Exceptions being thrown in the test about methods not existing on the Mock. I have tried for example:

 View::shouldReceive('make')
    ->once()
    ->andReturn(\Mockery::self())  

Adding this before I call the route results in a 500 error 'Method Mockery_1_Illuminate_View_Factory::with() does not exist on this mock object'. I tried adding in

->shouldReceive('with')
->once()
->andReturn(\Mockery::self());

However this results in an Exception stating that getData() does not exist on this Mock Object. Even removing that assertion, assertViewHas('badges') fails saying the response was not a view.

Also I haven't understood if View::shouldReceive... is part of Arrange or Assert phase of the test?My understanding it is part of the arrange and should go before the $this->action(....)

Aucun commentaire:

Enregistrer un commentaire