Ho cercato di testare gli eventi e l'ho fatto funzionare ieri. È stato prima che iniziassi a rifattare il codice di test per evitare che diventasse troppo ripetitivo. Ho aggiunto la chiamata al metodo setUp per generare i dati falsi usando ModelFactories. Questo è stato fatto in ogni caso di test di ieri e come dichiarato funzionava.Laravel 5.2 Test evento: attende che l'evento non venga attivato anche se è stato attivato
Sto pensando che abbia qualcosa a che fare con l'utilizzo del metodo setUp ma non ho idea del perché sia così. Per prima cosa ho tentato di utilizzare il metodo statico setUpBeforeClass() poiché viene eseguito una sola volta durante le esecuzioni di test delle unità. Tuttavia l'applicazione laravel non è in realtà impostata fino alla prima chiamata a setUp() ... Un possibile bug forse? È documentato in questo post SO Setting up PHPUnit tests in Laravel.
Pertanto ho optato per utilizzare il metodo setUp e solo per verificare se la proprietà statica è nullo o no, se è nullo quindi genera i dati, se non si va semplicemente in questo modo.
Ecco l'output da PHPUnit in esecuzione sul progetto
➜ project git:(laravel-5.2-testing) ✗ phpunit
PHPUnit 5.2.10 by Sebastian Bergmann and contributors.
E 1/1 (100%)
Time: 8.94 seconds, Memory: 33.50Mb
There was 1 error:
1) UserEmailNotificationsTest::testNotificationSentOnGroupMediaSaving
Exception: These expected events were not fired: [\App\Events\GroupMediaSaving]
/Users/jcrawford/Dropbox/Work/Viddler/Repositories/l5_media_communities/vendor/laravel/framework/src/Illuminate/Foundation/Testing/Concerns/MocksApplicationServices.php:44
/Users/jcrawford/Dropbox/Work/Viddler/Repositories/l5_media_communities/vendor/laravel/framework/src/Illuminate/Foundation/Testing/TestCase.php:127
FAILURES!
Tests: 1, Assertions: 0, Errors: 1, Skipped: 8.
Ecco il mio codice per il file di test di unità che ho creato.
<?php
use Illuminate\Foundation\Testing\WithoutMiddleware;
use Illuminate\Foundation\Testing\DatabaseMigrations;
use Illuminate\Foundation\Testing\DatabaseTransactions;
class UserEmailNotificationsTest extends \TestCase
{
use DatabaseTransactions;
const COMMUNITIES_TO_CREATE = 3;
const USERS_TO_CREATE = 10;
const ADMINS_TO_CREATE = 5;
protected static $communities = null;
protected static $users = null;
protected static $admins = null;
public function setUp()
{
parent::setUp(); // TODO: Change the autogenerated stub
if(is_null(self::$communities)) {
self::$communities = factory(\Community::class, self::COMMUNITIES_TO_CREATE)->create()->each(function ($community) {
self::$users[$community->id] = factory(User::class, self::USERS_TO_CREATE)->create()->each(function (\User $user) use ($community) {
$user->community()->associate($community);
$user->save();
});
self::$admins[$community->id] = factory(User::class, self::ADMINS_TO_CREATE, 'superadmin')->create()->each(function (\User $admin) use ($community) {
$admin->community()->associate($community);
$admin->save();
});
$community->save();
});
}
}
public static function getRandomCommunityWithAssociatedData()
{
$community = self::$communities[mt_rand(0, count(self::$communities)-1)];
return ['community' => $community, 'users' => self::$users[$community->id], 'admins' => self::$admins[$community->id]];
}
/**
* Test that the notification event is fired when a group media
* item is saved.
*/
public function testNotificationSentOnGroupMediaSaving()
{
$data = self::getRandomCommunityWithAssociatedData();
// FOR SOME REASON THIS SAYS THE EVENT IS NEVER FIRED WHEN IT ACTUALLY IS FIRED.
$this->expectsEvents(['\App\Events\GroupMediaSaving']);
$community = $data['community'];
$admin = $data['admins'][0];
$user = $data['users'][0];
$asset = factory(Asset\Video::class)->make();
$asset->community()->associate($community);
$asset->user()->associate($admin);
$asset->save();
$group = factory(Group::class)->make();
$group->community()->associate($community);
$group->created_by = $admin->id;
$group->save();
$groupMedia = factory(GroupMedia::class)->make();
$groupMedia->asset()->associate($asset);
$groupMedia->user()->associate($user);
$groupMedia->group()->associate($group);
$groupMedia->published_date = date('Y-m-d H:i:s', strtotime('-1 day'));
$groupMedia->save();
// I can print_r($groupMedia) here and it does have an ID attribute so it was saved, I also put some debugging in the event object and it is actually fired.....
}
}
Qualche idea sul motivo per cui non vede gli eventi che vengono generati? Trovo strano che siano licenziati se creo i modelli all'interno del test case ma sembra che stiano fallendo quando vengono eseguiti all'interno di setUp()
. La parte peggiore è che non sto creando il modello GroupMedia nel metodo setUp piuttosto che nel caso di test.
Ho anche scaricato i dati che vengono restituiti dal metodo getRandomCommunityWithAssociatedData
e restituisce gli oggetti modello corretti tutti con gli attributi id che mi dicono che sono stati tutti salvati nel database durante la creazione.
Come richiesto qui è il codice che sta effettivamente attivando l'evento, si trova nel modello GroupMedia nel metodo di avvio statico.
protected static function boot()
{
parent::boot();
static::saving(function($groupMedia) {
Event::fire(new \App\Events\GroupMediaSaving($groupMedia));
});
}
Non sono sicuro degli attributi statici (non giudicare, lo faccio solo in modo diverso, [esempio] (https: // github.com/timegridio/timegrid/blob/master/test/accettazione/scenari/consulenza/ConsultingScenarioTest.php)). Inoltre, come da [documentazione di laravel] (https://laravel.com/docs/master/testing) penso che non dovresti passare un array come argomento ma il ** Event ** stesso: '$ this-> expectsEvents (' \ App \ Events \ GroupMediaSaving '); 'o' $ this-> expectsEvents (App \ Events \ GroupMediaSaving :: class); ' – alariva
Ok, selezionato. È possibile passare un array come argomento. Ma anche, il percorso della tua classe di eventi è corretto? In PHP> = 5.5 puoi fare '$ this-> expectsEvents (App \ Events \ GroupMediaSaving :: class);', ti farà sapere se il percorso non è valido. – alariva
No, ho controllato i percorsi, sono tutti appropriati per i miei eventi e mappano le classi reali. –