Laravel - Как мне написать тест для этого? - PullRequest
1 голос
/ 04 июня 2019

Все еще довольно плохо знаком с тестированием и не могу решить это.Как я могу предотвратить запуск пакета Spatie здесь?Я просто хочу подделать ответ от него.

Пример контроллера:

<?php

namespace App\Http\Controllers;
use Spatie\SslCertificate\SslCertificate;

class SSLController extends Controller {

 function getIsValid(){

     $certificate = SslCertificate::createForHostName('https://example.url');

     return $certificate->isValid();

    }
}

Пример теста:

<?php 

namespace Tests\Unit;

use Tests\TestCase;
use Spatie\SslCertificate\SslCertificate;

class SSLCheckPlugInTest extends TestCase {

    public function it_returns_the_ssl_certs_status(){

         $this->mock(SslCertificate::class,function($mock){
            $mock->shouldReceive('createForHostName')->once();
        });

        $response = $this->get('/path-that-calls-the-controller-above');

    }
}

Этот пример кода все еще вызывает фактический вызов впакет (в example.url) и возвращает:

Mockery\Exception\InvalidCountException: Method createForHostName(<Any Arguments>) from Mockery_2_Spatie_SslCertificate_SslCertificate should be called
 exactly 1 times but called 0 times.

Мне кажется, что я упускаю что-то действительно очевидное.

edit

@Епископ предложил написать макет только для этого метода isValid, но я не могу понять, как это сделать.

Ответы [ 2 ]

1 голос
/ 05 июня 2019

Будет трудно высмеять SslCertificate, потому что вы используете его статически.

Вместо этого вы должны внедрить его в класс (или метод).Таким образом, он будет решен сервисным контейнером Laravel, поэтому вы сможете его смоделировать.

class SSLController extends Controller
{
    function getIsValid(SslCertificate $sslCertificate)
    {
        $certificate = $sslCertificate->createForHostName('https://example.url');

        return $certificate->isValid();
    }
}

class SSLCheckPlugInTest extends TestCase
{
    public function it_returns_the_ssl_certs_status()
    {
        $this->mock(SslCertificate::class, function ($mock) {
            $mock->shouldReceive('createForHostName')->once();
        });

        $response = $this->get('/path-that-calls-the-controller-above');
    }
}

Теперь, когда контроллер запущен, он проверитконтейнер для SslCertificate и найдите свой макет и оправдайте ожидания.

1 голос
/ 05 июня 2019

Метод $this->mock() в тестовых случаях Laravel специально предназначен для имитации экземпляра объекта в служебном контейнере Laravel. Из документов:

При издевательстве над объектом, который будет введен в ваш приложение через сервисный контейнер Laravel, вам нужно будет привязать ваш смоделированный instance в контейнер в качестве привязки экземпляра.

Вместо этого вы можете использовать Mockery напрямую для насмешки над другими классами или экземплярами, которые не будут загружены в контейнер службы.

По-моему, вы должны насмехаться над методами createForHostName и isValid. Цель вашего теста в основном тогда состоит в том, чтобы просто проверить, что ваш метод контроллера возвращает то, что он должен дать с известной достоверностью сертификата.

Сначала вы можете смоделировать экземпляр SslCertificate, который вы хотите вернуть из createForHostName, примерно так:

$certificateMock = Mockery::mock('overload:Spatie\SslCertificate\SslCertificate');
$certificateMock->shouldReceive('isValid')->once()->andReturn(True);

Мы перегружаем вышеприведенный класс, чтобы мы могли высмеивать как методы экземпляра, так и статические методы класса.

Затем вы можете смоделировать метод createForHostName для возврата экземпляра проверяемого класса сверху:

$certificateMock->shouldReceive('createForHostName')->once()->andReturn($certificateMock);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...