Comment se moquer d'un objet contextuel

8

J'essaie de tester un module qui contient un objet contextuel comme suit:

public function __construct(
    \Magento\Framework\App\Helper\Context $context,
    \Magento\Catalog\Model\Product\ImageFactory $productImageFactory,
    \Magento\Framework\View\Asset\Repository $assetRepo,
    \Magento\Framework\View\ConfigInterface $viewConfig,
    ProductRepository $productRepo
)
    {
    parent::__construct($context, $productImageFactory, $assetRepo, $viewConfig);
    $this->productRepo = $productRepo;
}

Lorsque j'exécute mon test unitaire, il me donne ce message d'erreur:

PHPUnit_Framework_Error : Argument 1 passed to Magento\Catalog\Model\Product::__construct() must be an instance of Magento\Framework\Model\Context, none given, called in ...

Comment puis-je me moquer de cet objet ou corriger cette erreur?

Amin Memariani
la source

Réponses:

7

Vous pouvez tester votre classe comme ceci:

public function testSomething() 
{
    $contextMock = $this->getMockBuilder(\Magento\Framework\App\Helper\Context::class)
         ->disableOriginalConstructor()
         ->getMock();
    $productImageFactoryMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\ImageFactory::class)
         ->disableOriginalConstructor()
         ->getMock();
    $assetRepoMock = $this->getMockBuilder(\Magento\Framework\View\Asset\Repository::class)
         ->disableOriginalConstructor()
         ->getMock();
    $viewConfigMock = $this->getMockBuilder(\Magento\Framework\View\ConfigInterface::class)
         ->disableOriginalConstructor()
         ->getMock();
    $productRepoMock = $this->getMockBuilder(\Magento\Catalog\Model\ProductRepository::class)
         ->disableOriginalConstructor()
         ->getMock();

    $productImageMock = $this->getMockBuilder(\Magento\Catalog\Model\Product\Image::class)
         ->disableOriginalConstructor()
         ->getMock();

    //mock here any methods you need to mock

    $productImageFactoryMock->method('create')->willReturn($productImageMock); 

    $model = new \The\Class\You\Want\To\Test( 
               $contextMock,
               $productImageFactoryMock,
               $assetRepoMock,
               $viewConfigMock,
               $productRepoMock
    ); 
    //do asserts here
}

Vous pouvez déplacer tout le faux bâtiment vers la setUp()méthode si vous devez faire plus d'un test.

Marius
la source
Merci pour la bonne réponse! mais je ne peux toujours pas me moquer de getSku () comme vous l'avez mentionné dans le code. donc je le poste ici: magento.stackexchange.com/questions/122785/… pouvez-vous s'il vous plaît me faire une faveur pour répondre à cela aussi? merci d'avance
Amin Memariani
3

Le code suivant créera une maquette du contexte dans votre test.

    $contextMock = $this->getMockBuilder(\Magento\Framework\App\Helper\Context::class)
        ->disableOriginalConstructor()
        ->getMock();

De: vendor/magento/module-sales/Test/Unit/Helper/DataTest.php:setup()

Vous devrez ensuite utiliser le pass $contextMockvia le gestionnaire d'objets:

$objectManager = new \Magento\Framework\TestFramework\Unit\Helper\ObjectManager($this);

$objectToTest = $objectManager->getObject(
        \Magento\Class\To\Test::class, [
            'context' => $contextMock,
            ...
        ]
    );

Ou vous pouvez utiliser un Mock et passer l'argument si vous avez besoin de changer la sortie de méthode de la classe que vous changez:

$objectToTest = $this->getMockBuilder(\Magento\Class\To\Test::class)
    ->setConstructorArgs([
        'context' => $contextMock
    ])->getMock();
jzahedieh
la source