Jobs
Much like the Mail facade in the previous section, implementing Jobs in your package is very similar to the workflow you'd go through in a Laravel application.
Creating a Job
First, create a new Jobs directory in the src/ directory of your package and add a PublishPost.php file, responsible for updating the 'published_at' timestamp of a Post. The example below illustrates what the handle() method could look like:
<?php
namespace JohnDoe\BlogPackage\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use JohnDoe\BlogPackage\Models\Post;
class PublishPost implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $post;
public function __construct(Post $post)
{
$this->post = $post;
}
public function handle()
{
$this->post->publish();
}
}
Testing Dispatching a Job
For this example, we have a publish() method on the Post model, which is already under test (a unit test for Post). We can easily test the expected behavior by adding a new PublishPostTest.php unit test in the tests/unit directory.
In this test, we can make use of the Bus facade, which offers a fake() helper to swap the real implementation with a mock. After dispatching the Job, we can assert on the Bus facade that our Job was dispatched and contains the correct Post.
<?php
namespace JohnDoe\BlogPackage\Tests\Unit;
use Illuminate\Support\Facades\Bus;
use JohnDoe\BlogPackage\Jobs\PublishPost;
use JohnDoe\BlogPackage\Models\Post;
use JohnDoe\BlogPackage\Tests\TestCase;
class PublishPostTest extends TestCase
{
/** @test */
public function it_publishes_a_post()
{
Bus::fake();
$post = Post::factory()->create();
$this->assertNull($post->published_at);
PublishPost::dispatch($post);
Bus::assertDispatched(PublishPost::class, function ($job) use ($post) {
return $job->post->id === $post->id;
});
}
}
As the test passes, you can safely make use of this Job in the package.