【问题标题】:Error: Cannot instantiate interface symfony when unit testing错误:单元测试时无法实例化接口 symfony
【发布时间】:2018-08-24 21:09:33
【问题描述】:

我正在尝试对注册方法进行单元测试,我正在关注此guide。我对单元测试相当陌生。

我一直在努力

1) App\Tests\Controller\SignUpControllerTest::testSignUp 错误:不能 实例化接口 Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface

/Applications/MAMP/htdocs/my_project/tests/Controller/SignUpControllerTest.php:19

我只是不认为我做这个单元测试是正确的。这就是我所拥有的。我不确定我在做什么。我要做的就是测试注册方法。

UserController.php

public function signup(Request $request, UserPasswordEncoderInterface $passwordEncoder )
{
    $user = new User();

    $entityManager = $this->getDoctrine()->getManager();

    $user->setEmail($request->get('email'));
    $user->setPlainPassword($request->get('password'));
    $user->setUsername($request->get('username'));
    $password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());
    $user->setPassword($password);

    $entityManager->persist($user);
    $entityManager->flush();

    return $this->redirectToRoute('login');



}

SignUpControllerTest.php

namespace App\Tests\Controller;

use App\Entity\Product;
use App\Controller\UserController;
use App\Entity\User;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectRepository;
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;

class SignUpControllerTest extends WebTestCase
{

    public function testSignUp()
    {   
        $passwordEncoder = new UserPasswordEncoderInterface();
        $user = new User();
        $user->setEmail('janedoe123@aol.com');
        $user->setPlainPassword('owlhunter');
        $user->setUsername('BarnMan');
        $password = $passwordEncoder->encodePassword($user, $user->getPlainPassword());
        $user->setPassword($password);

        $userRepository = $this->createMock(ObjectRepository::class);
        $userRepository->expects($this->any())
            ->method('find')
            ->willReturn($user);


        $objectManager = $this->createMock(ObjectManager::class);
        // use getMock() on PHPUnit 5.3 or below
        // $objectManager = $this->getMock(ObjectManager::class);
        $objectManager->expects($this->any())
            ->method('getRepository')
            ->willReturn($userRepository);

        $userController = new UserController($objectManager);
        $this->assertEquals(2100, $userController->signupTest());

    }


}

【问题讨论】:

  • 像往常一样:你不能实例化一个接口。这是基本的 PHP 东西。为什么不实例化实现该接口的正确密码编码器?
  • 已经 5 年了,我转向了 javascript/node react 的东西。所以不再关心这个了。

标签: php symfony


【解决方案1】:

错误很明显。在 testSignUp 方法的第一行中,您正在从接口中创建一个实例,而这在 PHP 中是无法完成的。

要在单元测试中从接口创建可用对象,请创建它的模拟对象。阅读 PHP 单元文档。

【讨论】:

    【解决方案2】:

    WebTestCase

    应用程序测试是 PHP 文件,通常位于应用程序的 tests/Controller/ 目录中,它告诉 Symfony 我们需要必要的工具来与我们的应用程序通信,就好像我们通过 HTTP 进行通信一样。

    内核测试

    用于从依赖注入容器中获取服务,它可以帮助您在测试中创建和启动内核

    这就是我推荐你使用 KernelTestCase 的原因

    use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase;
    
    class SignUpControllerTest extends KernelTestCase
    {
    private $passwordEncoder;
    
    protected function testSignUp(): void
    {
       self::bootKernel();
        $this->passwordEncoder= self::getContainer()->get('Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface');
    }
    
    public function addShoes3()
    {
         $passwordEncoder = $this->passwordEncoder;
        //continue
    }
    }
    

    【讨论】:

    • 请在您的答案中添加一些解释,以便其他人可以从中学习。您的代码如何解决给定的错误消息?
    • @NicoHaase 完成
    • “如果您请求的服务不存在” - 这与给定问题有什么关系?
    • @NicoHaase 我覆盖它我只是意味着接口不能实例化不退出
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-07-27
    • 1970-01-01
    • 1970-01-01
    • 2018-07-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多