Support the ongoing development of Laravel.io →
Requests Testing
Last updated 1 year ago.
0

There should be no difference between mocking facades using $this->action and $this->call

All facades can be mocked using shouldReceive on the facade

E.g.

<?php
//Routes.php
Route::resource('session');

//SessionController.php
class SessionController
{
	//...
	public function store()
	{
		$credentials = Input::only(['email', 'password'];
		if(Auth::attempt($credentials)) {
			return Redirect::intended('home.index');
		}
		return Redirect::route('session.create');
	}
	//...
}

//SessionTest.php
public function testCanLogin()
{
	$correctCredentials = [
		'email' => '[email protected]',
		'password' => 'password1'
	];
	Auth::shouldReceive('attempt')
		->with($credentials)
		->andReturn(true);

	$this->action('POST', 'SessionController@store', $credentials);

	$this->assertRedirectedToRoute('home.index');
}

Mocking injected properties can be done by binding a mock instance to a class E.g.

<?php
//Routes.php
Route::resource('session');

//SessionController.php
class SessionController
{
	protected $auth;

	public function __construct(Illuminate\Auth\AuthManager $auth) 
	{
		$this->auth = $auth;
	}

	//...
	public function store()
	{
		$credentials = Input::only(['email', 'password'];
		if($this->auth->attempt($credentials)) {
			return Redirect::intended('home.index');
		}
		return Redirect::route('session.create');
	}
	//...
}

//SessionTest.php
public function testCanLogin()
{
	$correctCredentials = [
		'email' => '[email protected]',
		'password' => 'password1'
	];
	$auth = Mockery::mock('Illuminate\Auth\AuthManager');
	$auth->shouldReceive('attempt')
		->with($credentials)
		->andReturn(true);
		
	$this->app->instance('Illuminate\Auth\AuthManager', $auth);

	$this->action('POST', 'SessionController@store', $credentials);

	$this->assertRedirectedToRoute('home.index');
}

As far as unit testing the route groups you have two options.

  1. This is not unit testing. In fact using call or action is not unit testing. It is integration testing because we are testing routes,filters, controllers and whatever other laravel magic is going on in one test. In order to truely unit test you need to instantiate the controller in the test and run the method directly with all dependencies (including facades mocked). Now whether we unit test or integration test it, one good way to check against a subdomain is to mock the Request facade or mock the injected request instance. You can then mock the method called on request to get the URL.

  2. Use acceptance testing with something like Behat\Selenium to test the system from the outside.

Last updated 1 year ago.
0

Sign in to participate in this thread!

Eventy

Your banner here too?

jamoy jamoy Joined 12 Jun 2014

Moderators

We'd like to thank these amazing companies for supporting us

Your logo here?

Laravel.io

The Laravel portal for problem solving, knowledge sharing and community building.

© 2024 Laravel.io - All rights reserved.