PHPUnit рдореЗрдВ рдпреВрдирд┐рдЯ рдЯреЗрд╕реНрдЯ рдХреА рд╕реНрд╡рд╛рдпрддреНрддрддрд╛

рд╕рднреА рдХреЛ рдирдорд╕реНрдХрд╛рд░!


рдореЗрд░рд╛ рдирд╛рдо рдПрдВрдЯреЛрди рд╣реИ рдФрд░ рдЕрдм (рдЗрддрдирд╛ рд▓рдВрдмрд╛ рдирд╣реАрдВ рд╣реИ, рдПрдХ рд╕рд╛рд▓ рдХреЗ рдмрд╛рд░реЗ рдореЗрдВ) рдореИрдВ рдПрдХ рдмрдбрд╝реЗ рдФрд░ рдкреБрд░рд╛рдиреЗ рдкреНрд░реЛрдЬреЗрдХреНрдЯ рдореЗрдВ PHP рдореЗрдВ рд╡рд┐рдХрд╛рд╕ рдХрд░ рд░рд╣рд╛ рд╣реВрдВред рдкрд░рд┐рдпреЛрдЬрдирд╛ рдХреА рдЧреБрдгрд╡рддреНрддрд╛ рд╕реБрдирд┐рд╢реНрдЪрд┐рдд рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП, рд╣рдо PHPUnit рдврд╛рдВрдЪреЗ рдкрд░ рдСрдЯреЛрдЯреЗрд╕реНрдЯ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреЗ рд╣реИрдВред рд▓реЗрдХрд┐рди, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рдРрд╕рд╛ рд╣реБрдЖ рдХрд┐ рд╣рдорд╛рд░реЗ рдЕрдзрд┐рдХрд╛рдВрд╢ рдСрдЯреЛрдЯреЗрд╕реНрдЯ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рд╣реИрдВред рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рд╣рдордиреЗ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ рдЕрдЧрд░ рд╣рдо рдЗрд╕реА рддрд░рд╣ рд╕реЗ рдСрдЯреЛрдЯреЗрд╕реНрдЯреНрд╕ рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рдирд╛ рдЬрд╛рд░реА рд░рдЦрддреЗ рд╣реИрдВ, рддреЛ рдЬрд▓реНрдж рд╣реА рд╕рдорд╕реНрдпрд╛рдУрдВ рдХреЛ рд╣рд▓ рдХрд░рдиреЗ рдореЗрдВ рд▓рдЧрдиреЗ рд╡рд╛рд▓рд╛ рд╕рдордп рд╕реАрдЖрдИ рдХреЗ рдкрд╛рд╕ рди рд╣реЛрдиреЗ рдХреЗ рдХрд╛рд░рдг рдЙрдкрдпреЛрдЧреА рдХреЛрдб рд▓рд┐рдЦрдиреЗ рдореЗрдВ рд▓рдЧрдиреЗ рд╡рд╛рд▓реЗ рд╕рдордп рд╕реЗ рдЕрдзрд┐рдХ рд╣реЛ рдЬрд╛рдПрдЧрд╛ (рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдирд╣реАрдВ, рд▓реЗрдХрд┐рди рдпрд╣ рдмрдврд╝рддрд╛ рд╣реИ рдФрд░ рдпрд╣ рдирд╣реАрдВ рд╣реИ рдЕрдЪреНрдЫреА рддрд░рд╣ рд╕реЗ)ред


рдЗрд╕ рд╕рдорд╕реНрдпрд╛ рдХреЗ рдПрдХ рд╡реНрдпрд╡рд╕реНрдерд┐рдд рд╕рдорд╛рдзрд╛рди рдХреЗ рд▓рд┐рдП, рд╣рдордиреЗ рдПрдХ рджреГрд╖реНрдЯрд┐рдХреЛрдг рдЪреБрдирд╛ рдЬрд┐рд╕рдореЗрдВ рдХрдИ рдпреВрдирд┐рдЯ рдкрд░реАрдХреНрд╖рдг рдФрд░ рдиреНрдпреВрдирддрдо рд╕рдВрдЦреНрдпрд╛ рдореЗрдВ рдХрд╛рд░реНрдпрд╛рддреНрдордХ рдкрд░реАрдХреНрд╖рдг рд▓рд┐рдЦрдирд╛ рд╢рд╛рдорд┐рд▓ рд╣реИред рд╣рдордиреЗ рдпрд╣ рднреА рдирд┐рд░реНрдгрдп рд▓рд┐рдпрд╛ рдХрд┐ рд╕реНрдХрд╛рдЙрдЯ рдирд┐рдпрдо рдХреЗ рдЕрдиреБрд╕рд╛рд░ рдЖрд╡рд╢реНрдпрдХ рдореМрдЬреВрджрд╛ рдХреЛрдб рдореЗрдВ рдкрд░рд┐рд╡рд░реНрддрди рдХреЗ рд╣рд┐рд╕реНрд╕реЗ рдХреЗ рд░реВрдк рдореЗрдВ, рдореМрдЬреВрджрд╛ рдкрд░реАрдХреНрд╖рдгреЛрдВ рдХреЛ рдЕрдкрдбреЗрдЯ рдХрд░реЗрдВред рдереЛрдбрд╝реА рджреЗрд░ рдХреЗ рд▓рд┐рдП - рдпрд╣ рд╕рдм рд╕рдордп рд╣рдордиреЗ рдирдИ рд╡рд┐рд╢реЗрд╖рддрд╛рдУрдВ рдХреЛ рджреЗрдЦрд╛ - рд╣рдорд╛рд░реЗ рд╕рд╛рде рд╕рдм рдХреБрдЫ рдареАрдХ рдерд╛ред рд▓реЗрдХрд┐рди рд╣рд╛рд▓ рд╣реА рдореЗрдВ, рдПрдХ рдХрд╛рд░реНрдп рдиреЗ рдкреБрд░рд╛рдиреЗ рдХреЛрдб рдореЗрдВ рдПрдХ рдмрдЧ рдХреЛ рдареАрдХ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рдореБрдЭрд╕реЗ рдЙрдбрд╝рд╛рди рднрд░реАред рдореИрдВрдиреЗ рдпреВрдирд┐рдЯ рдЯреЗрд╕реНрдЯ рд▓рд┐рдЦрдирд╛ рд╢реБрд░реВ рдХрд┐рдпрд╛ рдФрд░ рдорд╣рд╕реВрд╕ рдХрд┐рдпрд╛ рдХрд┐ рдкреНрд░рд╛рдЪреАрди рджреБрд╖реНрдЯ рд╡рд┐рд░рд╛рд╕рдд рдЬрд╛рдЧ рдЧрдИред рдпрд╣ рд╕реНрдкрд╖реНрдЯ рд╣реЛ рдЧрдпрд╛ рдХрд┐ рдпрд╣ рдХрд╣реАрдВ рдХрд╛ рд░рд╛рд╕реНрддрд╛ рд╣реИ:

  • рдореИрдВрдиреЗ рдХрдИ рдШрдВрдЯреЛрдВ рддрдХ рдХреБрдЫ рдкрд░реАрдХреНрд╖рдг рдорд╛рдорд▓реЛрдВ рдХреЛ рд▓рд┐рдЦрд╛;
  • рдореБрдЭреЗ рдорд╣рд╕реВрд╕ рд╣реБрдЖ рдХрд┐ рдЗрд╕ рджреМрд░рд╛рди рдореИрдВрдиреЗ рдПрдХ рдмрд╣реБрдд, рдмрд╣реБрдд рд╕реЗ рджреЛрд╣рд░рд╛рдП рдЧрдП рдХреЛрдб рд▓рд┐рдЦреЗ;
  • рд╡рд╛рд╕реНрддрд╡ рдореЗрдВ рдХреЛрдИ рдЙрдкрдпреЛрдЧреА рдХрд╛рдо рдирд╣реАрдВ рдХрд┐рдпрд╛;
  • рдбрд┐ рдореЗрдВ рдмрджрд▓рд╛рд╡ рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рдЖрдкрдХреЛ рдкрд░реАрдХреНрд╖рдг рдХреЛрдб рдХреЗ рдмреЗрдХрд╛рд░ рдЕрдиреБрдХреВрд▓рди рдкрд░ рдмрд╣реБрдд рд╕рдордп рдмрд┐рддрд╛рдирд╛ рд╣реЛрдЧрд╛ред


рдпрд╣ рд▓реЗрдЦ рдЗрд╕ рдмрд╛рд░реЗ рдореЗрдВ рд╣реИ рдХрд┐ рдореИрдВрдиреЗ рдХреИрд╕реЗ рд╡реИрдзрддрд╛ рдХреЛрдб рд▓рд┐рдЦрдиреЗ рд╕реЗ рдЗрдирдХрд╛рд░ рдХрд░рдиреЗ рдХреА рд╕рдорд╕реНрдпрд╛ рдХреЛ рд╣рд▓ рдХрд┐рдпрд╛ред рдХрдЯ рдХреЗ рддрд╣рдд - рдкрд░реАрдХреНрд╖рдг рдХреЗ рдорд╛рдорд▓реЗ рдХрд╛ рдЕрдВрддрд┐рдо рд░реВрдк, рдЕрдзрд┐рдХрд╛рдВрд╢ рдпрд╛рдВрддреНрд░рд┐рдХ рдХреЛрдб рдХреЗ рдЕрдкрд╡рд╛рдж рдХреЗ рд╕рд╛рде



рд▓реЗрдЦ рдХрд╛ рд╢реАрд░реНрд╖рдХ рдХрдВрдмрди рд╢реИрд▓реА рдореЗрдВ рд╕реНрд╡рдЪрд╛рд▓рди рдХреЛ рд╕рдВрджрд░реНрднрд┐рдд рдХрд░рддрд╛ рд╣реИ - рдПрдХ рддрд░рдл, рд╣рдордиреЗ рд╕реНрд╡рдЪрд╛рд▓рди рдХрд┐рдпрд╛, рдФрд░ рджреВрд╕рд░реА рдУрд░, рд╕рднреА рдкреНрд░рдореБрдЦ рдирд┐рд░реНрдгрдп рдПрдХ рд╡реНрдпрдХреНрддрд┐ рджреНрд╡рд╛рд░рд╛ рдХрд┐рдП рдЬрд╛рддреЗ рд╣реИрдВред

рдХреИрд╕реЗ рдХрд┐рдпрд╛


<?php declare(strict_types=1);
namespace Company\Bundle\Tests\Unit\Service;

use PHPUnit_Framework_MockObject_MockObject;

/**
 * @method \Company\Bundle\Service\TestedService getTestedClass()
 * @property PHPUnit_Framework_MockObject_MockObject|\Company\AnotherBundle\Repository\DependencyRepository $dependencyRepository
 * @property ConstDependencyInjectionParameter $diConstParam
 */
class TestedServiceTest extends Intelligent_PHPUnit_Framework_TestCase
{
    /**
     * @throws \Exception
     */
    public function test_getData_DataDescripion_ResultDescription(): void
    {
        // data
        $this
            ->diConstParam
            ->set("value")
        ;

        // behaviour
        $this
            ->dependencyRepository
            ->expects($this->once())
            ->method('findData')
            ->with(10, 10)
            ->will($this->returnValue([]))
        ;

        // SUT
        $clazz = $this->getTestedClass();

        // act
        $res = $clazz->getData();

        // asserts
    }
}

рдЬреИрд╕реЗ рдереЗ


рдЦрд░рд╛рдм рдерд╛ред рдирд┐рд░реНрднрд░рддрд╛ рдХреЗ рд▓рд┐рдП рдореЙрдмреНрд╕ рдХреА рдкреАрдврд╝реА рд╕реЗ рдПрдХ рдЕрдВрддрд╣реАрди рд╕реНрдкреЗрдЧреЗрдЯреА рдереА, рдкрд░реАрдХреНрд╖рдг рдХреЗ рдорд╛рдорд▓реЗ рдореЗрдВ рдХрдВрд╕реНрдЯреНрд░рдХреНрдЯрд░ рдХреЛ рдПрдХ рд▓рдВрдмреА рдХреЙрд▓ред рд╕рд╛рдорд╛рдиреНрдп рддреМрд░ рдкрд░, рдпрд╣ рдмрджрд╕реВрд░рдд рдерд╛, рдФрд░ рдХрд╣реАрдВ рди рдХрд╣реАрдВ рд▓реЗрдЦ рдХреЗ рдирд┐рдЪрд▓реЗ рднрд╛рдЧ рдореЗрдВ рдЗрд╕ рддрд░рд╣ рдХреЗ рдкрд░реАрдХреНрд╖рдг рдХрд╛ рдПрдХ рдЙрд▓реНрд▓реЗрдЦрдиреАрдп рд░реВрдк рд╕реЗ рдЙрджрд╛рд╣рд░рдг рджрд┐рдпрд╛ рдЧрдпрд╛ рд╣реИред


рд╣рдорд╛рд░реА рд╕реНрдерд┐рддрд┐рдпреЛрдВ рдореЗрдВ рдереЛрдбрд╝рд╛ рджрд░реНрдж


рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд╣рдорд╛рд░реА рдкрд░рд┐рдпреЛрдЬрдирд╛ PHPUnit 3.x рдХрд╛ рдЙрдкрдпреЛрдЧ рдХрд░рддреА рд╣реИред рд╣рд╛рдВ, рдореБрдЭреЗ рдкрддрд╛ рд╣реИ рдХрд┐ рдпрд╣ 2014 (!) рд╡рд░реНрд╖ рд╕реЗ рдкрд╣рд▓реЗ рд╣реА рд╕рдорд░реНрдерд┐рдд рд╣реЛрдирд╛ рдмрдВрдж рд╣реЛ рдЧрдпрд╛ рдерд╛, рд▓реЗрдХрд┐рди, рджреБрд░реНрднрд╛рдЧреНрдп рд╕реЗ, рд╣рдо рдЗрд╕реЗ рд╕реНрдерд╛рдиреАрдп рд╕рдордп рдХреЗ рдкреИрдорд╛рдиреЗ рдкрд░ рдордирд╛ рдирд╣реАрдВ рдХрд░ рд╕рдХрддреЗред


рд╣рд▓ рдХрд┐рдП рдЧрдП рдореБрджреНрджреЗ


, тАФ , , . , тАФ (, , 20) -, , , unit- , .


, , ┬л ┬╗ :

  1. setUp.
  2. tearDown. , ,
  3. -.



- . , . тАФ . . - , . тАж

рдХреЛрдб рдХреЗ рдЯреБрдХрдбрд╝реЗ рджреЛрд╣рд░рд╛рдиреЗ рдкрд░ рд╡рд┐рдЪрд╛рд░ рдХрд░реЗрдВред


рдирдХрд▓реА рдкреАрдврд╝реА


рдбреБрдкреНрд▓рд┐рдХреЗрдЯ рдХреЛрдб рд╕реНрдирд┐рдкреЗрдЯ:

$this->service = $this
    ->getMockBuilder(Service::class)
    ->disableOriginalConstructor()
    ->getMock()
;

рдПрдХ рдиреАрд░рд╕ рдХрд╛рдо рдХреЛ рдЫрд┐рдкрд╛рдиреЗ рдХреЗ рд▓рд┐рдП PHP рдХреЗ рдкрд╛рд╕ рдПрдХ рдЕрдЪреНрдЫрд╛ рдЙрдореНрдореАрджрд╡рд╛рд░ рд╣реИ - рдПрдХ рдЬрд╛рджреБрдИ рдХрд╛рд░реНрдп:

__рдкреНрд░рд╛рдкреНрдд

рд▓реЗрдХрд┐рди рд╣рдореЗрдВ рдЕрднреА рднреА рдЙрд╕ рдкреНрд░рдХрд╛рд░ рдХреЛ рд╡реНрдпрдХреНрдд рдХрд░рдирд╛ рд╣реЛрдЧрд╛ рдЬрд┐рд╕реЗ рд╣рдо рдЧреАрд▓рд╛ рдХрд░ рд░рд╣реЗ рд╣реИрдВред рдФрд░ рдлрд┐рд░ рдПрдХ рдЙрдкрдпреБрдХреНрдд рдЙрдкрдХрд░рдг рдорд┐рд▓рд╛ - phpDoc:

@property рдкреНрд░рдХрд╛рд░ $ рд╕реЗрд╡рд╛

рд╣рдорд╛рд░реЗ рдорд╛рдорд▓реЗ рдореЗрдВ, рд╡рд┐рд╢реЗрд╖ рд░реВрдк рд╕реЗ рдЖрдзреБрдирд┐рдХ рдЖрдИрдбреАрдИ рдХреА рдХреНрд╖рдорддрд╛рдУрдВ рдХреЛ рдзреНрдпрд╛рди рдореЗрдВ рд░рдЦрддреЗ рд╣реБрдП, рдпрд╣ рдирд┐рдореНрдирд▓рд┐рдЦрд┐рдд рдкреНрд░рд╛рд░реВрдк рдореЗрдВ рдЗрд╕реЗ рд╕реЗрдЯ рдХрд░рдиреЗ рдХреЗ рд▓рд┐рдП рд╕рдмрд╕реЗ рд╕реБрд╡рд┐рдзрд╛рдЬрдирдХ рдирд┐рдХрд▓рд╛:
@property \ FQCN \ Service | \ PHPUnit_Framework_MockObject_MockObject $ рд╕реЗрд╡рд╛

рд╕рд╛рд░ рд╡рд░реНрдЧ Intellegence_PHPUnit_Framework_TestCase рдХреЗ __get рдлрд╝рдВрдХреНрд╢рди рдХреЗ рдЕрдВрджрд░, рдореЗрдЯрд╛рдкреНрд░реЛрдЧреНрд░рд╛рдорд┐рдВрдЧ рд╣реЛрддреА рд╣реИ, рдЬреЛ phpDoc рдХреЛ рдкрд╛рд░реНрд╕ рдХрд░рддреА рд╣реИ рдФрд░ рдЗрд╕рдХреЗ рдЖрдзрд╛рд░ рдкрд░ рдореЛрдХреНрд╕ рдмрдирд╛рддреА рд╣реИ, рдЬреЛ рдкрд░реАрдХреНрд╖рдг рд╡рд░реНрдЧ рдореЗрдВ $-> рдкреНрд░реЙрдкрд░реНрдЯреАрдирд╛рдо рдкрд░ рдЙрдкрд▓рдмреНрдз рд╣реИрдВред рдзреНрдпрд╛рди рджреЗрдВ, рд▓реЗрдЦ рдореЗрдВ рджрд┐рдП рдЧрдП рд╕рднреА рдХреЛрдб рдереЛрдбрд╝рд╛ рдЫрджреНрдо рдХреЛрдб рд╣реИ, рдкреВрд░реНрдг рд╕рдВрд╕реНрдХрд░рдг рд░рд┐рдкреЙрдЬрд┐рдЯрд░реА рдореЗрдВ рд╣реИ:


abstract class Intelligent_PHPUnit_Framework_TestCase extends PHPUnit_Framework_TestCase {
   public function __get(string $name)
    {
        // propertyBag     ,        phpDoc property
        $property = $this->getPropertyBag()->get($name);
        if ($property === false) {
            throw new Exception("Invalid property name: ${name}");
        }

        return $property;
    }

    private function getPropertyBag(): PropertyBag
    {
            if ($this->propertyBag === null) {
               //     
               $this->propertyBag = (new DocCommentParser())
                   ->parse(
                        //    phpDoc   FQCN .   FQCN  ,      
                        get_class($this),
                        //     callback,   getMockBuilder -     unit-
                        function (string $className): PHPUnit_Framework_MockObject_MockObject {
                            return $this->createDefaultObjectMock($className);
                        }
                    );
            }

            return $this->propertyBag;
    }
}

, phpDoc . :


class DocCommentParser
{
    /**
     * @param string $className
     * @param callable $mockCreator
     * @throws Exception
     * @return PropertyBag
     */
    public function parse(
        string $className,
        callable $mockCreator
    ): PropertyBag {
        /** @var string[] $res */
        $r = new ReflectionClass($className);
        //   phpDoc
        $docComment = $r->getDocComment();

        if ($docComment === false) {
            return new PropertyBag([]);
        }

        return $this->parseDocString($docComment, $mockCreator);
    }

    private function parseDocString(
        string $docComment,
        callable $mockCreator
    ): PropertyBag {
        /** @var string[] $map */
        $map = [];
        /** @var string[] $constructorParams */
        $constructorParams = [];

        //   -  : property Type1|Type2 $propertyName
        //    mock,   DI     ,   
        preg_match_all('/@property\s*(?<mock>(\S*)\|(\S+)\s*\$(\S+))/', $docComment, $matches, PREG_SET_ORDER);
        foreach ($matches as $match) {
            if (array_key_exists('mock', $match) && !empty($match['mock'])) {
                //        -    
                //   
                if ($this->isMockObject($match[2])) {
                    $map[$match[4]] = $mockCreator($match[3]);
  
                    continue;
                }

                if ($this->isMockObject($match[3])) {
                    $map[$match[4]] = $mockCreator($match[2]);

                    continue;
                }
            }
        }

        return new PropertyBag($map);
    }
}

? , тАФ FQCN phpDoc property . тАФ , .


2
.

-


class ServiceTest extends PHPUnit_Framework_TestCase
{
    /** @var DependencyRepository|PHPUnit_Framework_MockObject_MockBuilder */
    private $repository;
    protected function setUp()
    {
        parent::setUp();
        $this
            ->repository = $this->getMockBuilder(DependencyRepository::class)
            ->disableOriginalConstructor()
            ->getMock()
        ;    
    }

    protected function tearDown()
    {
        $this->repository = null;
        parent::tearDown();
    }

    public function test_test()
    {
         // $this->repository = ...
    }
}


/** @property PHPUnit_Framework_MockObject_MockObject|\Company\AnotherBundle\Repository\DependencyRepository $repository */
class ServiceTest extends Intelligent_PHPUnit_Framework_TestCase
{
    public function test_test()
    {
         // $this->repository = ...
    }
}


3-4-5 ( ) тАФ . , , , 7 тАФ . , 20 тАФ -.



. ! -, , .


:


public function test_case()
{
    // SUT
    //   , ,    DI    .
    // ,      DI.
    $this->clazz = $this->createTestClass(
        $dependency1,
        $dependency2,
        $dependency3 //, ...
    );
}

, . php __call, phpDoc method.


, , ?! , property! , . , property тАФ . тАФ , .


, :


/**
 * @method FQCN\TestedService getTestedClass()
 */
class ServiceTest
{
    public function test_case()
    {
         // SUT
         $clazz = $this->getTestedClass();
    }
}

__call:


abstract class Intelligent_PHPUnit_Framework_TestCase extends PHPUnit_Framework_TestCase
{
    private const GET_TESTED_CLASS_METHOD_NAME = 'getTestedClass';

    /**
     * @param string $method
     * @param array $params
     * @throws Exception
     * @return object
     */
    public function __call(string $method, array $params)
    {
        if ($method !== self::GET_TESTED_CLASS_METHOD_NAME) {
            throw new Exception("Invalid method name: ${method}");
        }

        if (!array_key_exists(self::GET_TESTED_CLASS_METHOD_NAME, $this->getMethodsMap())) {
            throw new Exception('Method ' . self::GET_TESTED_CLASS_METHOD_NAME . ' not annotated');
        }

        //  ,  PropertyBag        property -    
        $params = $this->getPropertyBag()->getConstructorParams();
        $paramValues = [];
        foreach ($params as $param) {
            $property = $this->__get($param);
            $paramValues[] = $property;
        }

        $reflection = new ReflectionClass($this->getMethodsMap()[self::GET_TESTED_CLASS_METHOD_NAME]);
        //         
        return $reflection->newInstanceArgs($paramValues);
    }
}

? property:


class DocCommentParser
{
    /**
     * @param string $className
     * @param callable $mockCreator
     * @throws Exception
     * @return PropertyBag
     */
    public function parse(
        string $className,
        callable $mockCreator
    ): PropertyBag {
        /** @var string[] $res */
        $r = new ReflectionClass($className);
        $docComment = $r->getDocComment();

        if ($docComment === false) {
            //     
            return new PropertyBag([], []);
        }

        return $this->parseDocString($docComment, $mockCreator);
    }

    private function parseDocString(
        string $docComment,
        callable $mockCreator
    ): PropertyBag {
        /** @var string[] $map */
        $map = [];
        /** @var string[] $constructorParams */
        $constructorParams = [];

        preg_match_all('/@property\s*(?<mock>(\S*)\|(\S+)\s*\$(\S+))/', $docComment, $matches, PREG_SET_ORDER);
        foreach ($matches as $match) {
            if (array_key_exists('mock', $match) && !empty($match['mock'])) {
                if ($this->isMockObject($match[2])) {
                    $map[$match[4]] = $mockCreator($match[3]);
                    //    
                    $constructorParams[] = $match[4];

                    continue;
                }

                if ($this->isMockObject($match[3])) {
                    $map[$match[4]] = $mockCreator($match[2]);
                    //    
                    $constructorParams[] = $match[4];

                    continue;
                }
            }
        }

        return new PropertyBag($map, $constructorParams);
    }
}

. , . , DI - , , , тАФ ,


-


class ServiceTest extends PHPUnit_Framework_TestCase
{
    /** @var DependencyRepository|PHPUnit_Framework_MockObject_MockBuilder */
    private $repository;
    protected function setUp()
    {
        parent::setUp();
        $this
            ->repository = $this->getMockBuilder(DependencyRepository::class)
            ->disableOriginalConstructor()
            ->getMock()
        ;    
    }

    protected function tearDown()
    {
        $this->repository = null;
        parent::tearDown();
    }

    public function test_test()
    {
        $this->clazz = $this->createTestClass(repository);
    }

    private function createTestClass() {
        return new TestedService($repository)
    }
}


тАФ . .

3
.


ConstDependencyInjectionParameter. , .



All Articles