调用成员函数validated()on null(单元测试Laravel 9)

nx7onnlm  于 2023-01-18  发布在  其他
关注(0)|答案(1)|浏览(166)

我正在为一些控制器方法编写测试,这些方法将验证请求数据并通过第三方API创建文档。然后它应该返回带有201状态代码的响应。我正在使用模拟来模拟正在创建文档的服务类。下面是我的控制器:

public function margin(MarginRequest $request){
    $data = $request->validated();

    $fileId = $this->documentService->createDocument(auth()->user()->id, SignableDocumentAbstract::MARGIN_CERTIFICATE, new MarginDocument(), $data);

    return response()->json([
        'code' => 201,
        'message' => 'Margin agreement generated successfully',
        'data' => [
            'uuid' => $fileId
        ]
    ], 201);
}

我的测试:

public function test_public_margin()
{
    $marginData = (new MarginFaker())->fake();

    Auth::shouldReceive('user')->once()->andReturn((object)['id' => 999999]);

    $this->mock(DocumentService::class, function (MockInterface $mock) {
        $mock->shouldReceive('createDocument')
            ->once()
            ->andReturn(Str::random());
    });

    $request = MarginRequest::create('/api/public/documents/margin', 'POST', $marginData);

    $response = app(PublicController::class)->margin($request);

    $this->assertEquals(201, $response->getStatusCode());
}

一切看起来正常,但当我运行我的测试时,它抛出错误
Call to a member function validated() on null
它是在控制器的$data = $request->validated();行中给出的。但是我不明白为什么我的$request被识别为null。即使我通过dump($request)转储请求对象,我也可以看到它是对象,并在其中包含所有必需的字段。
那么是什么原因,为什么我在测试时不能调用validated()方法?

qc6wkl3g

qc6wkl3g1#

当你想测试一个URL时,你不能这样测试,你不能模拟一个控制器或者做new Controller并调用它里面的一个方法。
您必须阅读HTTP Test section of the documentation
因此,您的测试应该如下所示:

public function test_public_margin()
{
    $this->actingAs(User::factory()->create());

    $this->mock(DocumentService::class, function (MockInterface $mock) {
        $mock->shouldReceive('createDocument')
            ->once()
            ->andReturn(Str::uuid());
    });

    $response = $this->post(
        '/api/public/documents/margin', 
        ['pass the needed data as an array, so the validation passes']
    );

    $response->assertStatus(201);
}

相关问题