wipflash's avatar

Writing Unit test with mokery

I want to write a unit test using mockery for following example code block.

protected function evaluate(): EvaluationResult
    {
        try {
            $smtpTransport = \App::make(\Swift_SmtpTransport::class, [
                'host' => config('mail.host'),
                'port' => config('mail.port'),
                'encryption' => config('mail.encryption')
            ])->setUsername(config('mail.username'))->setPassword(config('mail.password'));

            $mailer = \App::make(\Swift_Mailer::class, ['transport' => $smtpTransport]);
            $mailer->getTransport()->start();

            $connectionmade = true;
        } catch (\Exception $e) {
            $connectionmade = false;
        }

        return new EvaluationResult(
            ($connectionmade) ? SystemHealthStatus::SUCCESS() : SystemHealthStatus::FAILED(),
            ($connectionmade) ? 'Mail server connection established' : 'No mail server connection could be established',
            new \DateTimeImmutable()
        );
    }
0 likes
3 replies
bugsysha's avatar

Use dependency injection and pass in mocked objects.

wipflash's avatar

Can you give me simple example? because I am new to this

bugsysha's avatar

Bind following into the container in AppServiceProvider using examples https://laravel.com/docs/7.x/container#binding-basics

$smtpTransport = \App::make(\Swift_SmtpTransport::class, [
                'host' => config('mail.host'),
                'port' => config('mail.port'),
                'encryption' => config('mail.encryption')
            ])->setUsername(config('mail.username'))->setPassword(config('mail.password'));

$mailer = \App::make(\Swift_Mailer::class, ['transport' => $smtpTransport]);
            $mailer->getTransport()->start();

Then remove all that from that method and in that class use __construct to get those dependencies.

public function __construct(\Swift_SmtpTransport $smtpTransport, \Swift_Mailer $mailer)
{
	$this->smtpTransport = $smtpTransport;
	$this->mailer = $mailer;
}

Then in your tests, you do something like:

$smtpTransport = $this->mock(\Swift_SmtpTransport::class);
$mailer = $this->mock(\Swift_Mailer::class);

$sut = new XYZ($smtpTransport, $mailer);
$sut->callPublicMethod();

// add your assertions here.

Please or to participate in this conversation.