如果在调度作业后抛出异常,如何测试作业参数。下面的测试返回绿色,但我发现无法测试作业参数。
代码:
<?php
namespace Tests\Feature;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Tests\TestCase;
class SomeJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function handle() {}
}
class NothingTest extends TestCase
{
/** @test */
public function dispatch_test()
{
$this->expectException(\Exception::class);
$this->expectsJobs(SomeJob::class);
// job dispatched and Exception thrown afterwards
dispatch(new SomeJob("argument to test"));
throw new \Exception();
}
}
答案 0 :(得分:1)
我今天早些时候遇到了这个问题。我为解决这个问题所做的是使用withoutJobs()
方法。 (内部expectsJobs()
也会调用它。)然后,您可以对dispatchedJobs
属性进行断言。
因为你在测试中也“期待”和异常,你应该将它包装在一个回调中并在beforeApplicationDestroyed()
class SomeJob {
private $argument;
public function __construct($argument)
{
$this->argument = $argument;
}
}
class NothingTest extends TestCase
{
/** @test */
public function dispatch_test()
{
$this->expectException(\Exception::class);
$this->beforeApplicationDestroyed(function () {
// This part depends on how you would like to design this. You could
// use public properties, add a getter method on your job or use
// something like reflection to compare the properties.
$dispatchedJob = $this->dispatchedJobs[0];
$this->assertEquals(
'argument to test',
$this->getValue($dispatchedJob, 'argument')
);
});
// job dispatched and Exception thrown afterwards
dispatch(new SomeJob("argument to test"));
throw new \Exception();
}
protected function getValue($object, $name)
{
$ro = new \ReflectionObject($object);
$property = $ro->getProperty($name);
$property->setAccessible(true);
return $property->getValue($object);
}
}
答案 1 :(得分:0)
确定。可以测试如下代码。 测试看起来不错,但必须使用公共属性并将所有参数分配给属性。
<?php
namespace Tests\Examples;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Queue\SerializesModels;
use Tests\TestCase;
class SomeJob implements ShouldQueue
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public $arg1;
public $arg2;
public function __construct($arg1, $arg2)
{
$this->arg1 = $arg1;
$this->arg2 = $arg2;
}
public function handle() {}
}
class JobTest extends TestCase
{
/** @test */
public function dispatch_test()
{
$this->expectException(\Exception::class);
$this->expectsJobs(SomeJob::class);
$this->testJobInstance(SomeJob::class, function($job){
$this->assertEquals('arg1', $job->arg1);
$this->assertEquals('arg2', $job->arg2);
});
// job dispatched and Exception thrown afterwards
dispatch(new SomeJob("arg1", "arg2"));
throw new \Exception();
}
// will be pushed up to TestCase
protected function testJobInstance($class, callable $callback)
{
$this->beforeApplicationDestroyed(function () use($class, $callback) {
$job = collect($this->dispatchedJobs)->filter(function($job) use($class) {
return get_class($job) == $class;
})->first();
$callback($job);
});
}
}
答案 2 :(得分:0)
好的,找到了更好的方法......
我已经帮助从IOC派遣工作 - 这使得测试工作变得更加容易。
/**
* @param string | object $job
* @param array | null $args - associative array of arguments ['agr1' => 'value', 'arg2' => 2]
* @return mixed
*/
function dispatch_from_ioc($job, ? array $args)
{
if (is_string($job)) {
$job = app()->makeWith($job, $args);
}
return app(Dispatcher::class)->dispatch($job);
}
所以现在我可以测试这样的工作论点:
/** @test */
public function test_jobs_arguments()
{
$this->app->bind(
RealJob::class,
function($app, $args){
// assertions against arguments
$this->assertEquals("argument", $args["arg"]);
$this->assertEquals([], $args["arg2"]);
return new FakeJob;
}
);
// System under test
dispatch_from_ioc(RealJob::class, ["arg" => "argument", "arg2" => []]);
}
假工作班
<?php
namespace App\Jobs;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Foundation\Bus\Dispatchable;
class FakeJob extends Job
{
use Dispatchable, InteractsWithQueue, Queueable, SerializesModels;
public function __construct() {}
public function handle() {}
}
有意义吗? :)