【问题标题】:Failed unit /functional testing symfony 4.2失败的单元/功能测试 symfony 4.2
【发布时间】:2019-01-24 08:59:01
【问题描述】:

我正在编写用于在 symfony 4.2 中执行单元测试的代码,实际上是在使用 JWT 身份验证包来生成令牌。我想测试令牌是否生成成功。如果需要改进,请查看并建议我。

登录控制器中的代码

<?php

namespace App\Controller;

use App\Entity\Organization;
use Doctrine\Common\Annotations\AnnotationReader;
use Lexik\Bundle\JWTAuthenticationBundle\Services\JWTTokenManagerInterface;
use Psr\Log\LoggerInterface;
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 Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Component\Security\Core\User\UserProviderInterface;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Encoder\XmlEncoder;
use Symfony\Component\Serializer\Mapping\Factory\ClassMetadataFactory;
use Symfony\Component\Serializer\Mapping\Loader\AnnotationLoader;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;

class LoginController extends AbstractController
{
protected $serializer;

protected $logger;

public function __construct(LoggerInterface $logger)
{
    $this->logger = $logger;
    $encoders = array(new XmlEncoder(), new JsonEncoder());
    $classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
    $normalizer = new ObjectNormalizer($classMetadataFactory);
    $normalizer->setCircularReferenceLimit(2);
    $normalizer->setCircularReferenceHandler(function ($object) {
        return $object->getId();
    });
    $normalizers = array($normalizer);
    $this->serializer = new Serializer($normalizers, $encoders);
}

/**
 * Check the credentials are valid
 * Check whether the user is verified
 * Generate JWT token for authentic users and return
 *
 * @Route("/api/login_check", name="login_check")
 */
public function login(Request $request, JWTTokenManagerInterface $JWTTokenManager, UserProviderInterface $userProvider, UserPasswordEncoderInterface $encoder)
{
    try {
        $data = json_decode($request->getContent());
        $user = $userProvider->loadUserByUsername($data->email);
        $passwordValid = $encoder->isPasswordValid($user, $data->password);
        if ($passwordValid) {
            if ($user->getVerified()) {
                $organization = $user->getOrganization();
                $organization = $this->getDoctrine()->getRepository(Organization::class)->findOneBy(array('id' => $organization->getId()));
                $token = $JWTTokenManager->create($user);
                return new JsonResponse(['token' => $token, 'user' => $this->serializer->normalize($user, 'json')]);
            } else {
                $array = array('message' => 'User not verified');
                $response = new Response(json_encode($array), 401);
                $response->headers->set('Content-Type', 'application/json');
                return $response;
            }
        } else {
            $array = array('message' => 'Bad credentials');
            $response = new Response(json_encode($array), 401);
            $response->headers->set('Content-Type', 'application/json');
            return $response;
        }
    } catch (\Exception $e) {
        return new Response($e->getMessage());
    }
}
}

测试/控制器文件夹中的代码

    namespace App\Tests\Controller

use App\Controller\Log;
use App\Controller\LoginController;
use PHPUnit\Framework\TestCase;
use PHPUnit\Framework\MockObject\MockObject;
use Psr\Log\LoggerInterface;

class LoginTest extends TestCase{

    protected $logger;
    protected $controller;
/**
 *
 */
public function setUp()
{
    $this->logger = $this->createMock(LoggerInterface::class);

    $this->controller = new LoginController(
        $this->logger
    );

    parent::setUp();
}

public function testlogin()
{
    $result = $this->controller->login('Test');
    $this->assertEquals( 'TEST1548303737',$result);
}

}

【问题讨论】:

  • 您的问题到底是什么?你的测试有错误吗?

标签: php unit-testing symfony


【解决方案1】:

您的“登录”操作需要 2 个参数,您需要将 Request 和 JWTManagerInterface 模拟到。

另一个想法:用 Symfony 功能测试替换单元测试。 示例(改编自 symfony 文档):

namespace App\Tests\Controller;

use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;

class LoginControllerTest extends WebTestCase
{
    public function testCheckLogin()
    {
        $client = static::createClient();
        $client->request('POST', '/api/login_check', [], [], [], 'test');

        $this->assertEquals(200, $client->getResponse()->getStatusCode());
        $this->assertEquals('TEST1548303737', $client->getResponse()->getContent());
    }
}

【讨论】:

    【解决方案2】:

    你只需要mock请求和JWT管理界面

    【讨论】:

      猜你喜欢
      • 2020-08-07
      • 1970-01-01
      • 2016-03-05
      • 2019-07-17
      • 1970-01-01
      • 1970-01-01
      • 2015-05-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多