Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

DTOs passed to controller actions are not mapped correctly in tests #54570

Closed
Labels
@floriankraemer

Description

@floriankraemer

Symfony version(s) affected

7.0.*

Description

I'm following the official documentation regarding tests and DTOs but I get this error when running the test. The code itself works, I've tried the API with Postman. But the test seemingly has a problem to map the request to the DTO for some reason. The error I get is this:

1) App\Tests\Feature\SignUp\Application\Http\Controller\Api\SignUpControllerTest::testSuccessfulSignUpSymfony\Component\DependencyInjection\Exception\RuntimeException: Cannot autowire service "App\Feature\SignUp\Application\Transfer\ProfileTransfer": argument "$firstName" of method "__construct()" is type-hinted "string", you should configure its value explicitly.

The DTO looks like they are describedin the documentation and the controller works, but the test has trouble. They arenested DTOs, I have a SignUpTransfer that then is using an UserTransfer and a ProfileTransfer.

SignUpTransfer|--UserTransfer |--ProfileTransfer

And use it in the controller#[MapRequestPayload] SignUpTransfer $signUpTransfer:

    #[Route(        path:'/api/sign-up',        name:'api_sign_up',        methods: ['POST']    )]publicfunctionsignUp(        #[MapRequestPayload]SignUpTransfer$signUpTransfer    ):JsonResponse|ErrorResponse {//...    }

ProfileTransfer:

<?phpdeclare(strict_types=1);namespaceApp\Feature\SignUp\Application\Transfer;useSymfony\Component\Validator\ConstraintsasAssert;readonlyclass ProfileTransfer{publicfunction__construct(        #[Assert\NotBlank()]        #[Assert\Length(min:2, max:64)]publicstring$firstName,        #[Assert\NotBlank()]        #[Assert\Length(min:2, max:64)]publicstring$lastName    ) {    }publicfunctiongetFirstName():string    {return$this->firstName;    }publicfunctiongetLastName():string    {return$this->lastName;    }}

SignUpTransfer

<?phpdeclare(strict_types=1);namespaceApp\Feature\SignUp\Application\Transfer;useSymfony\Component\Validator\ConstraintsasAssert;readonlyclass SignUpTransfer{publicfunction__construct(        #[Assert\NotNull()]        #[Assert\Valid()]publicUserTransfer$user,        #[Assert\NotNull()]        #[Assert\Valid()]publicProfileTransfer$profile    ) {    }publicfunctiongetUser():UserTransfer    {return$this->user;    }publicfunctiongetProfile():ProfileTransfer    {return$this->profile;    }}

The test code

<?phpdeclare(strict_types=1);namespaceApp\Tests\Feature\SignUp\Application\Http\Controller\Api;usePsr\Http\Message\MessageInterface;usePsr\Http\Message\ServerRequestInterface;useSymfony\Bundle\FrameworkBundle\Test\WebTestCase;class SignUpControllerTestextends WebTestCase{protectedfunctionapiRequest(string$url,string$method,$data,$parameters = [],$files = [])    {returnstatic::createClient()->request(            method:$method,            uri:$url,            parameters:$parameters,            files:$files,            server: ['HTTP_ACCEPT' =>'application/json','CONTENT_TYPE' =>'application/json'            ],            content:json_encode($data,JSON_THROW_ON_ERROR),            changeHistory:true        );    }publicfunctiontestSuccessfulSignUp():void    {$this->apiRequest('/sign-up','POST', ['user' => ['email' =>'testmail@test.local','password' =>'password','confirmPassword' =>'password'            ],'profile' => ['firstName' =>'John','lastName' =>'Doe'            ]        ]);self::assertResponseStatusCodeSame(201);self::assertResponseHeaderSame('Content-Type','application/json');    }}

The code works, the problem is the test. I can call the endpoint via Postman without problems:

enter image description here

How to reproduce

Created a DTO with child DTOs like this structure:

SignUpTransfer|--UserTransfer |--ProfileTransfer

And try to call the API endpoint with the test client.

<?phpdeclare(strict_types=1);namespace App\Tests\Feature\SignUp\Application\Http\Controller\Api;use Psr\Http\Message\MessageInterface;use Psr\Http\Message\ServerRequestInterface;use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;class SignUpControllerTest extends WebTestCase{    protected function apiRequest(string $url, string $method, $data, $parameters = [], $files = [])    {        return static::createClient()->request(            method: $method,            uri: $url,            parameters: $parameters,            files: $files,            server: [                'HTTP_ACCEPT' => 'application/json',                'CONTENT_TYPE' => 'application/json'            ],            content: json_encode($data, JSON_THROW_ON_ERROR),            changeHistory: true        );    }    public function testSuccessfulSignUp(): void    {        $this->apiRequest('/sign-up', 'POST', [            'user' => [                'email' => 'testmail@test.local',                'password' => 'password',                'confirmPassword' => 'password'            ],            'profile' => [                'firstName' => 'John',                'lastName' => 'Doe'            ]        ]);        self::assertResponseStatusCodeSame(201);        self::assertResponseHeaderSame('Content-Type', 'application/json');    }}

Possible Solution

I have not yet investigated it but there must be a difference to how the real request is handled and the one from the test client.

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions


      [8]ページ先頭

      ©2009-2025 Movatter.jp