Вы можете попробовать создать фиктивного потомка корневого класса, который использует Artisan Facade, и переопределить любой метод, который выполняет нежелательные действия.А затем, в вашем тесте, позвоните Artisan::swap($dummyObj);
, чтобы заменить его.
-
Это не очень хорошо задокументировано, я думаю, что столкнулся с этим, когда я искал детальный способразрешить запуск некоторых событий в моем тесте и запретить другим избегать побочных действий.Так что Illuminate\Support\Facades\Event::fake()
является хорошим примером того, как это использовать.
Итак, заглянем под капот:
config/app.php
определяет Artisan
как указывающий на Illuminate\Support\Facades\Artisan
. Illuminate\Support\Facades\Artisan::getFacadeAccessor()
определяет имя средства доступа к фасаду как имя интерфейса Illuminate\Contracts\Console\Kernel
. - И интерфейс ядра привязан к одиночному элементу App \ Console \ Kernel в * 1021.*.
Все в сумме, это означает, что каждый раз, когда вы звоните по \Artisan
, вы на самом деле говорите с повторно используемым экземпляром App\Console\Kernel
.
App\Console\Kernel
extends Illuminate\Foundation\Console\Kernel
, и , что - это то, что обладало командой call()
, для которой вы хотели бы управлять поведением.
Итак, вы хотите что-то вроде этого:
namespace Tests\Dummies;
use App\Console\Kernel as BaseKernel;
class Artisan extends BaseKernel
{
// This will override the parent's call() and block it from doing anything.
public function call($command, array $parameters = [], $outputBuffer = null)
{
// -- Do nothing instead, or add some debug logging here --
}
}
Затем, в качестве первого действия внутри вашего теста или части метода setUp()
, выполните:
$dummyArtisan = app(Tests\Dummies\Artisan::class);
Artisan::swap($dummyArtisan);
Обратите внимание, что все это не проверено.Я делал подобные вещи в прошлом и могу с уверенностью сказать, что теория солидна.Но я не знаю, является ли этот конкретный код.
-
Возможно, вы также захотите взглянуть на Illuminate\Support\Facades\Facade::spy()
и Illuminate\Support\Facades\Facade::shouldReceive()
.Я просто заметил их, когда смотрел код здесь, чтобы написать этот ответ, и они заставляют меня задуматься, не изобрело ли мое предложение немного колесо заново.Похоже, что Фасады спроектированы с небольшим осознанием того, что их сложно издеваться, поэтому у них есть некоторые инструменты для этого.