Back to Course |
Testing in Laravel 11: Advanced Level

Fake in Packages: Laravel Excel Example

After repeating many examples with Laravel Facades and their fake() method in this course chapter, I will show you one more thing. Some Laravel/PHP packages have their own implementation of faking.


Package Example

For example, a popular package Laravel Excel can be faked in the test. An example from the docs for testing Excel exporting:

/**
* @test
*/
public function user_can_download_invoices_export()
{
Excel::fake(); // [tl ~~]
 
$this->actingAs($this->givenUser())
->get('/invoices/download/xlsx');
 
Excel::assertDownloaded('filename.xlsx', function(InvoicesExport $export) {
// Assert that the correct export is downloaded.
return $export->collection()->contains('#2018-01');
});
}

An example from the docs for testing Excel importing:

/**
* @test
*/
public function user_can_import_users()
{
Excel::fake();
 
$this->actingAs($this->givenUser())
->get('/users/import/xlsx');
 
Excel::assertImported('filename.xlsx', 'diskName');
 
Excel::assertImported('filename.xlsx', 'diskName', function(UsersImport $import) {
return true;
});
 
// When passing the callback as 2nd param, the disk will be the default disk.
Excel::assertImported('filename.xlsx', function(UsersImport $import) {
return true;
});
}

There are more assertions for exporting and importing. Check the documentation.


Open-Source Example

Let's examine a real-world example from an open-source akaunting/akaunting project.

There are three tests: two for exporting (all transactions or only selected ones) and one for importing.

Exporting tests use regex to match file names and check that the row count is correct.

Importing tests also use another fake to upload a file.

tests/Feature/Banking/TransactionsTest.php:

use App\Models\Banking\Transaction;
use Illuminate\Http\UploadedFile;
use Illuminate\Support\Facades\File;
use Maatwebsite\Excel\Facades\Excel;
 
class TransactionsTest extends FeatureTestCase
{
// ...
 
public function testItShouldExportTransactions()
{
$count = 5;
Transaction::factory()->income()->count($count)->create();
 
Excel::fake();
 
$this->loginAs()
->get(route('transactions.export'))
->assertStatus(200);
 
Excel::matchByRegex();
 
Excel::assertDownloaded(
'/' . str()->filename(trans_choice('general.transactions', 2)) . '-\d{10}\.xlsx/',
function (Export $export) use ($count) {
// Assert that the correct export is downloaded.
return $export->collection()->count() === $count;
}
);
}
 
public function testItShouldExportSelectedTransactions()
{
$create_count = 5;
$select_count = 3;
 
$transactions = Transaction::factory()->income()->count($create_count)->create();
 
Excel::fake();
 
$this->loginAs()
->post(
route('bulk-actions.action', ['group' => 'banking', 'type' => 'transactions']),
['handle' => 'export', 'selected' => $transactions->take($select_count)->pluck('id')->toArray()]
)
->assertStatus(200);
 
Excel::matchByRegex();
 
Excel::assertDownloaded(
'/' . str()->filename(trans_choice('general.transactions', 2)) . '-\d{10}\.xlsx/',
function (Export $export) use ($select_count) {
return $export->collection()->count() === $select_count;
}
);
}
 
public function testItShouldImportTransactions()
{
Excel::fake();
 
$this->loginAs()
->post(
route('transactions.import'),
[
'import' => UploadedFile::fake()->createWithContent(
'transactions.xlsx',
File::get(public_path('files/import/transactions.xlsx'))
),
]
)
->assertStatus(200);
 
Excel::assertImported('transactions.xlsx');
 
$this->assertFlashLevel('success');
}
 
// ...
}