coder2 Aynı model için birden fazla factory oluşturamazsınız. Onun için state kullanacaksınız. State içerisinde define ile tanımladığınız factory içerisindeki değerleri ezebilirsiniz. Belli bir stateden sonra işlem yaptırmak için ise afterCreating yerine afterCreatingState kullanacaksınız.
$factory->define(User::class, function (Faker $faker) {
return [
'title' => null,
// Diğer alanlar...
];
});
$factory->state(App\User::class, 'user', [
'title' => 'Kullanıcı',
// Burada diğer alanları ezebilirsiniz...
]);
$factory->state(App\User::class, 'moderator', [
'title' => 'Moderatör',
// Burada diğer alanları ezebilirsiniz...
]);
$factory->state(App\User::class, 'admin', [
'title' => 'Yönetici',
// Burada diğer alanları ezebilirsiniz...
]);
// factory eğer moderator state ile kullanılırsa çalışacak
$factory->afterCreatingState(App\User::class, 'moderator', function ($user, $faker) {
$user->assignRole('moderator');
});
// factory eğer admin state ile kullanılırsa çalışacak
$factory->afterCreatingState(App\User::class, 'admin', function ($user, $faker) {
$user->assignRole('admin');
});
// Kullanıcıların title değerleri Kullanıcı olacak, rol yok:
$users = factory(App\User::class, 5)->states('user')->make();
// Kullanıcıların title değerleri Moderatör ve hepsi moderator rolüne sahip olacak:
$moderators = factory(App\User::class, 5)->states('moderator')->make();
// Kullanıcıların title değerleri Yönetici ve hepsi admin rolüne sahip olacak:
$admins= factory(App\User::class, 5)->states('admin')->make();
// Kullanıcıların title değerleri ilkini ezdiği için Yönetici olacak,
// hepsi moderator ve admin rolüne sahip olacak:
$admins= factory(App\User::class, 5)->states('moderator', 'admin')->make();
---
Mocking olayına gelince, mesela kullanıcı oluşturduktan sonra event(new UserCreated($user)) şeklinde bir event ateşlediğinizi düşünün. Bunu test ederken ateşlenip ateşlenmediğini test edersiniz. Bunu yaparken de tanımlı listener'ın çalışmasını istemezsiniz. Örneğin SMS gönderiyordur, bir yerlere dosya atıyordur vs bunları test sırasında yapmasını istemezsiniz. Onlar ayrı test edilir. Mock burada devreye giriyor ve listener olayı yakalamadan olayın ateşlenip ateşlenmediğini test etmenizi sağlıyor. Yani fake atıyorsunuz.
public function testUserCreated()
{
Event::fake();
// Burada UserCreated olayını ateşleyen bir işlem çalıştırmanız lazım. Ben elle ateşliyorum.
// Onu ateşleyen bir endpointe istek de atabilirsiniz. Burası sizin nasıl kod yazdığınıza
// göre, neyi test edeceğinize göre şekillenir.
$user = factory(App\User::class)->states('user')->make();
event(new UserCreated($user));
// UserCreated olayını dinleyen örneğin bir SendSMSNotification dinleyicisi varsa herhangi bir işlem
// yapmayacak. Sadece olayın ateşlenip ateşlenmediğini test edeceğiz. İşte burada eğer
// UserCreated içerisinde bir işlem yaptıysanız o ne yazık ki çalışacak ve tam olarak
// mocking gerçekleşmeyecek. Yani test edilebilir kod yazmamış olacaksınız...
Event::assertDispatched(function (UserCreated $event) use ($user) {
// Olay ateşlenmiş ise içeride oluşturduğumuz User var demektir
// O yüzden içerideki ile dışarıdaki karşılaştırıldığında bize olayın
// ateşlenip ateşlenmediğini verir.
return $event->user->id === $user->id;
});
// $user ile ilgili başka işlemler varsa buradan devam ediyorsunuz...
}
Test edilebilir kod yazmadığınız sürece test, mocking vs hiçbiri bir anlam ifade etmiyor, bunu unutmayın. Test işi gerçekten zor. TDD (Test-Driven Development) daha da zor. Her ne kadar bazıları mümkün olmadığını, kimsenin o kadar kaynağı olmadığını söylese de bana göre bir projenin test edilebilir bir proje olarak kodlanabilmesi için önce kağıt üzerinde bitmesi gerekir, her şeyiyle. Bana göre test yazmakta zorlanmamızın sebebi bizim projelerimizin tamamlanmış bir taslaktan değil de bir fikirden ve tasklardan yola çıkarak kodlanırken, yolda şekillenmesi ve tamamlanması. Size 100 parçalı bir maket versem ve desem ki bu bir uzay aracı olacak. Önce gövdeyi yapacağız, sonra motorları vs. Siz bunu yaparken birçok kez parçaları tak çıkar yapacaksınız, yerlerini değiştireceksiniz, yanlış taktığınız yerler olacak, parçaları söküp orayı düzeltip tekrar diğerlerini birleştireceksiniz vs... ta ki ne zaman biterse fakat size maketten önce maketin şemasını versem, siz şemayı görünce bile elinize ilk alacağınız ve son alacağınız parçayı bilirsiniz.