laravel - 如何在 Laravel 中模拟 Job 对象?
问题描述
在 Laravel 中进行队列测试时,我使用了提供的Queue Fake功能。但是,在某些情况下,我需要为 Job 类创建一个 Mock。
我有以下代码将作业推送到 Redis 支持的队列:
$apiRequest->storeRequestedData($requestedData); // a db model
// try-catch block in case the Redis server is down
try {
App\Jobs\ProcessRunEndpoint::dispatch($apiRequest)->onQueue('run');
$apiRequest->markJobQueued();
} catch (\Exception $e) {
//handle the case when the job is not pushed to the queue
}
我需要能够测试 catch 块中的代码。因此,我试图模拟 Job 对象,以便能够创建一个会引发异常的伪造者。
我在我的单元测试中试过这个:
ProcessRunEndpoint::shouldReceive('dispatch');
该代码返回:Error: Call to undefined method App\Jobs\ProcessRunEndpoint::shouldReceive()
。我还尝试使用模拟对象交换作业实例,$this->instance()
但效果不佳。
也就是说,我如何测试 catch 块中的代码?
解决方案
根据文档,您应该能够通过为队列提供的模拟来测试作业。
Queue::assertNothingPushed();
// $apiRequest->storeRequestedData($requestedData);
// Use assertPushedOn($queue, $job, $callback = null) to test your try catch
Queue::assertPushedOn('run', App\Jobs\ProcessRunEndpoint::class, function ($job) {
// return true or false depending on $job to pass or fail your assertion
});
使该行App\Jobs\ProcessRunEndpoint::dispatch($apiRequest)->onQueue('run');
抛出异常有点复杂。dispatch()
只是返回一个对象,onQueue()
只是一个二传手。那里没有其他逻辑。相反,我们可以通过弄乱配置让一切都失败。
而不是Queue::fake();
,用一个不起作用的覆盖默认队列驱动程序:Queue::setDefaultDriver('this-driver-does-not-exist');
这将使每个作业调度失败并抛出一个ErrorException
.
极简主义示例:
Route::get('/', function () {
try {
// Job does nothing, the handle method is just sleep(5);
AJob::dispatch();
return view('noError');
} catch (\Exception $e) {
return view('jobError');
}
});
namespace Tests\Feature;
use App\Jobs\AJob;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Foundation\Testing\WithFaker;
use Illuminate\Support\Facades\Queue;
use Tests\TestCase;
class AJobTest extends TestCase
{
/**
* @test
*/
public function AJobIsDispatched()
{
Queue::fake();
$response = $this->get('/');
Queue::assertPushed(AJob::class);
$response->assertViewIs('noError');
}
/**
* @test
*/
public function AJobIsNotDispatched()
{
Queue::setDefaultDriver('this-driver-does-not-exist');
$response = $this->get('/');
$response->assertViewIs('jobError');
}
}
推荐阅读
- ms-access - DoCmd.OpenForm 需要很长时间才能触发 Form_Load 事件,表示查询正在运行 (Access 2016)
- python - _ldap.get_option(_ldap.OPT_API_INFO) 升级到 MacOS Mojave 后变慢
- javafx - 尝试将 JavaFX connect4 游戏与学校服务器一起使用
- polymer - 如何在 Polymer 2/3 中使用基于模板的元素?
- javascript - JavaScript 可以选择类名以 (...) 开头的所有元素吗?
- python - 使用 stunnel 建立与 DUKASCOPY 的连接
- angular5 - 使用 Angular 在 Nativescript 中显示 *ngFor 的动态对象键
- python - ProcessPoolExecutor、BrokenProcessPool 处理
- xcode - 无法构建 InAppSettingsKitSampleApp
- r - 获得非常嵌套的元素(RSelenium),但是如何?