首页 > 解决方案 > php+symfony - phpunit 测试 - 无法实例化接口错误

问题描述

我正在尝试编写我的第一个 php 单元测试。但我得到下一个错误:

错误:无法实例化接口 Doctrine\Persistence\ManagerRegistry

是什么原因,我该如何解决?我正在使用 PHP + Symfony。这是一个服务控制器的代码示例,我在其中使用了函数 add:

class OrdersService
{
    protected $ordersRepository;
    protected $manager;
    protected $router;

    public function __construct(OrdersRepository $ordersRepository, EntityManagerInterface $manager, RouterInterface $router)
    {
        $this->ordersRepository = $ordersRepository;
        $this->manager = $manager;
        $this->router = $router;
    }

    public function add($shoesid, $sizeid) {
        $cart = $this->session->get('cart', []);

        if(!empty($cart[$shoesid][$sizeid])) {
            if(($cart[$shoesid][$sizeid]) < 3){
                $cart[$shoesid][$sizeid]++;
            } else {
                $cart[$shoesid][$sizeid] = 3;
            }
            
        } else {
            $cart[$shoesid][$sizeid] = 1;
        }
        
        $this->session->set('cart', $cart);
    }
}

这是测试的代码:

class OrderTest extends TestCase
{
    public function addShoes3()
    {
        $registry = new ManagerRegistry();
        $ordersRepository = new OrdersRepository($registry);
        $router = new RouterInterface();

        $ordersService = new OrdersService($ordersRepository, $manager, $router);
        $actual = $ordersService->add(40002, 400);
        $expected = $ordersService->add(40002, 400);

        $this->assertEquals($expected, $actual);
    }
} 

标签: phpunit-testingsymfonydoctrinephpunit

解决方案


正如错误消息告诉您的那样:在您的测试中,您尝试使用new ManagerRegistry(). 但是你不能实例化接口。

OrdersService有这些服务,因为你将它们添加为构造函数参数并且 symfony 的依赖注入组件处理它们的创建。

在您的单元测试中,您通常不希望拥有所有这些依赖项的真实实例(具有所有它们自己的依赖项等)。相反,您想要一个模拟版本。一个模拟,就像它是真实的对象一样。因此,您需要为所有依赖项创建模拟并将它们添加到OrdersService您的测试中:

public function addShoes3()
{
    $registry = $this->createMock(ManagerRegistry::class);
    $ordersRepository = $this->createMock(OrdersRepository::class);
    $router = $this->createMock(RouterInterface::class);

    $ordersService = new OrdersService($ordersRepository, $manager, $router);
    $actual = $ordersService->add(40002, 400);
    $expected = $ordersService->add(40002, 400);

    $this->assertEquals($expected, $actual);
}

推荐阅读