为什么returnValueMap()返回null



试图在测试中模拟学说存储库,与 findOneby 方法一起使用时,returnValueMap((总是返回null。p>我嘲笑了两个实体,然后尝试使用给定的返回值映射嘲笑其存储库。测试失败和调试表明returnValueMap((正在返回null。

这是要测试的类(否定器(

<?php
declare(strict_types=1);
namespace AppSerializer;
use AppEntityAdditionalService;
use AppRepositoryAdditionalServiceRepository;
use DtoAdditionalServiceCollection;
use SymfonyComponentSerializerNormalizerDenormalizerInterface;
class AdditionalServiceCollectionDenormalizer implements DenormalizerInterface
{
    /** @var AdditionalServiceRepository */
    private $additionalServiceRepository;
    public function __construct(AdditionalServiceRepository $additionalServiceRepository)
    {
        $this->additionalServiceRepository = $additionalServiceRepository;
    }
    public function denormalize($mappedCsvRow, $class, $format = null, array $context = [])
    {
        $addtionalServicesCollection = new AdditionalServiceCollection();
        foreach ($mappedCsvRow as $fieldName => $fieldValue) {
            /** @var AdditionalService $additionalService */
            $additionalService = $this->additionalServiceRepository->findOneBy(['name'=>$fieldName]);
            if ($additionalService) {
                $addtionalServicesCollection->add($additionalService->getId(), $fieldValue);
            }
        }
        return $addtionalServicesCollection;
    }
    public function supportsDenormalization($data, $type, $format = null)
    {
        return $type instanceof  AdditionalServiceCollection;
    }
}

这是我的测试课:

<?php
namespace AppTestsImportConfig;
use AppEntityAdditionalService;
use AppRepositoryAdditionalServiceRepository;
use AppSerializerAdditionalServiceCollectionDenormalizer;
use PHPUnitFrameworkTestCase;
use DtoAdditionalServiceCollection;
class AddionalServiceCollectionDenormalizerTest extends TestCase
{
    public function provider()
    {
        $expected = new AdditionalServiceCollection();
        $expected->add(1, 22.1)->add(2, 3.1);
        return [
            [['man_1' => 22.1], $expected],
            [['recycling' => 3.1], $expected],
        ];
    }
    /**
     * @dataProvider provider
     * @covers AppSerializerAdditionalServiceCollectionDenormalizer::denormalize
     */
    public function testDenormalize(array $row, AdditionalServiceCollection $exptected)
    {
        $manOneService = $this->createMock(AdditionalService::class);
        $manOneService->expects($this->any())->method('getId')->willReturn(1);
        $recycling = $this->createMock(AdditionalService::class);
        $recycling->expects($this->any())->method('getId')->willReturn(2);
        $additionalServicesRepoMock = $this
            ->getMockBuilder(AdditionalServiceRepository::class)
            ->setMethods(['findOneBy'])
            ->disableOriginalConstructor()
            ->getMock();
        $additionalServicesRepoMock
            ->expects($this->any())
            ->method('findOneBy')
            ->will($this->returnValueMap(
                [
                    ['name'=>['man_1'], $manOneService],
                    ['name'=>['recycling'], $recycling],
                ]
            ));
        $denormalizer = new AdditionalServiceCollectionDenormalizer($additionalServicesRepoMock);
        self::assertEquals($exptected, $denormalizer->denormalize($row, AdditionalServiceCollection::class));
    }
}

我很难调试phpunit库,最终确定是findOneby((方法期望两个参数,其中第二个参数是可选的(设置为null(

willreturnmap((方法如下:

/**
 * Stubs a method by returning a value from a map.
 */
class ReturnValueMap implements Stub
{
    /**
     * @var array
     */
    private $valueMap;
    public function __construct(array $valueMap)
    {
        $this->valueMap = $valueMap;
    }
    public function invoke(Invocation $invocation)
    {
        $parameterCount = count($invocation->getParameters());
        foreach ($this->valueMap as $map) {
            if (!is_array($map) || $parameterCount !== (count($map) - 1)) {
                continue;
            }
            $return = array_pop($map);
            if ($invocation->getParameters() === $map) {
                return $return;
            }
        }
        return;
    }

我怀疑该方法始终是由于未满足的条件$parameterCount !== (count($map) - 1)而返回的。一个断点证实了我的疑问,还揭示了$invocation->getParameters()转储如下:

array(2) {
  [0] =>
  array(1) {
    'name' =>
    string(5) "man_1"
  }
  [1] =>
  NULL
}

因此,我必须明确将null作为第二个参数。最后,工作地图必须为:

$this->additionalServicesRepoMock
            ->method('findOneBy')
            ->willReturnMap([
                [['name' => 'man_1'], null, $manOneService],
                [['name' => 'recycling'], null, $recyclingService],
            ]);

它看起来像testDenormalize()returnValueMap()的参数需要括号以使其索引阵列。

这是phpunit文档中代码段的稍微修改的版本:

<?php
namespace AppTests;
use PHPUnitFrameworkTestCase;
class ReturnValueMapTest extends TestCase
{
    public function testReturnValueMapWithAssociativeArray()
    {
        $stub = $this->createMock(SomeClass::class);
        $map = [
            [
                'name' => ['man_1'],
                'Hello'
            ],
        ];
        $stub->method('doSomething')
            ->will($this->returnValueMap($map));
        // This will fail as doSomething() returns null
        $this->assertSame('Hello', $stub->doSomething(['name' => ['man_1']]));
    }
    public function testReturnValueMapWithIndexedArray()
    {
        $stub = $this->createMock(SomeClass::class);
        $map = [
            [
                ['name' => ['man_1']], // Notice the difference
                'Hello'
            ],
        ];
        $stub->method('doSomething')
            ->will($this->returnValueMap($map));
        $this->assertSame('Hello', $stub->doSomething(['name' => ['man_1']]));
    }
}
class SomeClass
{
    public function doSomething()
    {}
}

相关内容

  • 没有找到相关文章

最新更新