如何在Laravel 5中测试表单请求规则?

12

我创建了一个表单请求类并定义了一堆规则。现在我想测试这些规则,以查看行为是否符合我们的预期。

我该如何编写测试来完成这个任务?

非常感谢您提前的答复!

更新:更准确地说,我想编写一个单元测试,检查格式不正确的电子邮件是否通过验证。问题是我不知道如何创建一个有虚假输入的 Request 实例。


2
这里有一个类似的回答:https://dev59.com/TFoU5IYBdhLWcg3w5p2a - Dov Benyomin Sohacheski
可能是 Unit Test Laravel 的 FormRequest 的重复问题。 - Yevgeniy Afanasyev
朋友们,请好好做单元测试,毕竟你在这里测试的不仅是规则,还有可能涉及到validationData和withValidator函数。这是我的答案 - Yevgeniy Afanasyev
3个回答

22

接受的答案同时测试授权和验证。如果您想单独测试这些功能,则可以执行以下操作:

测试rules()

$attributes = ['aa' => 'asd'];
$request = new MyRequest();
$rules = $request->rules();
$validator = Validator::make($attributes, $rules);
$fails = $validator->fails();
$this->assertEquals(false, $fails);

测试 authorize()

$user = factory(User::class)->create();
$this->actingAs($user);
$request = new MyRequest();
$request->setContainer($this->app);
$attributes = ['aa' => 'asd'];
$request->initialize([], $attributes);
$this->app->instance('request', $request);
$authorized = $request->authorize();
$this->assertEquals(true, $authorized);

你应该在基类中创建一些辅助方法,以保持测试代码DRY。


根据您的验证逻辑的复杂程度(例如,如果您正在通过代码在Request类中组装rules数组),您将希望在创建Request对象后添加此行以将$attributes数组分配给自定义的Request类:$request->replace($attributes); - tmountjr
我不太明白你在单元测试中如何导入 Validator。它是一个门面类,对吗? - Zac
@Zac:是的,你是对的。你需要从 Illuminate\Support\Facades\Validator 导入 Validator。 - Marco

2
您需要在控制器函数中拥有您的表单请求类,例如:
public function store(MyRequest $request)

现在创建HTML表单并尝试使用不同的值填充它。如果验证失败,则会在会话中获取消息,如果成功,则进入控制器函数。

进行单元测试时,请调用URL并添加测试用的值作为数组。 Laravel文档称可以这样做

$response = $this->call($method, $uri, $parameters, $cookies, $files, $server, $content);

你好,感谢你的回答!不过这并不是我想要的:s 我觉得我的问题表述得比较差,所以我更新了它。我想做的是编写一个单元测试来检查我编写的验证规则是否正确。 - kant312
改进了我的回答。 - Margus Pala
8
这似乎有点牵强。你应该只关注请求对象,而不依赖于URI、cookie等其他因素,这样做是否更好? - Dov Benyomin Sohacheski
@DovBenyominSohacheski 虽然这种方法是“有效”的,但绝对不是最佳实践。正如你所说的,当单元测试时,除了被测试的类/函数之外的所有内容都应该被模拟/存根。 - chesscov77
@Juan,请查看以下链接,以获取不同的解决方案:https://dev59.com/TFoU5IYBdhLWcg3w5p2a#37096837 - Dov Benyomin Sohacheski

2
以下是一个完整的测试验证示例:
use App\Http\Requests\PostRequest;
use Illuminate\Routing\Redirector;
use Illuminate\Validation\ValidationException;

class PostRequestTest extends TestCase
{
    protected function newTestRequest($data = [])
    {
        $request = new PostRequest();

        $request->initialize($data);

        return $request
            ->setContainer($this->app)
            ->setRedirector($this->app->make(Redirector::class));
    }

    public function testValidationFailsWhenEmptyTitleIsGiven()
    {
        $this->expectException(ValidationException::class);

        $this->newTestRequest(['title' => ''])->validateWhenResolved();
    }
}

Steve 总是那么厉害...正好是我需要的。 - Grant

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接