首页 > 解决方案 > POST 端点上的 PHPUnit 测试用例返回 400

问题描述

我创建了一个简单的控制器 post 端点,它可以与 postman 一起正常工作,但是 phpunit 测试用例确实失败并且不返回预期的 201 代码

这是我的控制器,我在其中创建了简单的 post 端点

namespace App\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use App\Entity\User;

class UserController extends AbstractController
{
    /**
     * @Route("/api/users", name="user", methods="POST")
     */
    public function post(Request $request): Response
    {
        $users = $request->toArray()['users'];//request body
        $usersArray = array('users'=>array());//response body
        $api_key = "d195e8fb160ff29935bce1fe6772253b18ac92d6b74f1f7407c8cbafbf439d3e";
//        $api_key = $request->headers->get('api-key');

        if($api_key && hash('sha256', 'testtest') === $api_key){

            foreach($users as $user){
                $newUser = new User();
                $newUser->setFirstName($user['first_name']);
                $newUser->setLastName($user['last_name']);
                $newUser->getFullName();
                array_push($usersArray['users'], $newUser);
            }

            return new Response(
                json_encode($usersArray),
                JsonResponse::HTTP_CREATED
            );
        }
        else {
            return new JsonResponse(
                ["Message" => "Api_key 'd195e8fb160ff29935bce1fe6772253b18ac92d6b74f1f7407c8cbafbf439d3e' is either incorrect or empty"],
                JsonResponse::HTTP_UNAUTHORIZED
            );
        }

    }
}

这是我的课

namespace App\Entity;

class User
{
    private $first_name;

    private $last_name;

    public $full_name;

    public function getFirstName()
    {
        return $this->first_name;
    }

    public function setFirstName($first_name)
    {
        $this->first_name = $first_name;
    }

    public function getLastName()
    {
        return $this->last_name;
    }

    public function setLastName($last_name)
    {
        $this->last_name = $last_name;
    }


    public function getFullName()
    {
        return $this->full_name = $this->getFirstName()." ".$this->getLastName();;
    }
}

这是测试

<?php


namespace App\Tests;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class UserControllerTest extends WebTestCase
{
    public function testUser()
    {
        $client = self::createClient();
        $client->request('POST', '/api/users', ['json' => [
            'users' => ['first_name'=>'Abraomas','last_name'=>'Linkolnas'],['first_name'=>'Abraomas','last_name'=>'Linkolnas']]
        ]);
        $this->assertEquals(201, $client->getResponse()->getStatusCode());
    }
}

这是我跑步时得到的php bin/phpunit

Testing Project Test Suite
F                                                                   1 / 1 (100%)

Time: 463 ms, Memory: 20.00 MB

There was 1 failure:

1) App\Tests\UserControllerTest::testUser
Failed asserting that 400 matches expected 201.

D:\Users\Gediminas\Desktop\Symfony\tlb-final\tests\UserControllerTest.php:16

FAILURES!
Tests: 1, Assertions: 1, Failures: 1.

Other deprecation notices (1)

  1x: Since symfony/monolog-bridge 5.2: Passing an actionLevel (int|string) as constructor's 3rd argument of "Symfony\Bridge\Monolog\Handler\FingersCrossed\HttpCodeActivationStrategy" is deprecated, "Monolog\Handler\FingersCrossed\A
ctivationStrategyInterface" expected.
    1x in UserControllerTest::testUser from App\Tests

在邮递员中,此帖子端点与请求正文一起正常工作

{
    "users": [
        {
            "first_name": "Abraomas",
            "last_name": "Braomas"
        },
        {
            "first_name": "Braomas",
            "last_name": "Abraomas"
        }
    ]
}

响应正文

{
    "users": [
        {
            "full_name": "Abraomas Braomas"
        },
        {
            "full_name": "Braomas Abraomas"
        }
    ]
}

标签: phpapirestclasssymfony

解决方案


首先尝试这是否可行

$this->client->request(
    'POST', 
    '/api/users',  
    [],
    [],
    ['CONTENT_TYPE' => 'application/json'],
    '{"users":[{"first_name":"Abraomas","last_name":"Braomas"},{"first_name":"Braomas","last_name":"Abraomas"}]}'
);

如果是这样,请尝试前面的示例,但不要用户json键入数组并手动添加内容类型

但是每次你应该做的第一件事就是知道如何找到问题以及如何调试它。很明显的是,你的问题出在你行动开始的某个地方

$users = $request->toArray()['users'];//request body

为什么不简单地dd($request->toArray());在这个分配之后添加并检查你会在测试运行时看到什么?


推荐阅读