0

I've created an API extension that manages gallery easily for our demands and now I wanted to create a unit testing.

For example, one functionality is: give an 'sku' and 'entry' object (with base64 img) and API adds this image on that product.

This is the class I want to test:

<?php

namespace Gsp\ApiExtension\Model;

use Gsp\ApiExtension\Api\SGIMediaInterface;
use Magento\Framework\Api\ImageContentValidatorInterface;
use Magento\Catalog\Api\ProductAttributeMediaGalleryManagementInterface;
use Magento\Catalog\Api\Data\ProductAttributeMediaGalleryEntryInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Store\Api\StoreRepositoryInterface;
use Magento\Framework\App\ObjectManager;

class SGIMedia implements SGIMediaInterface {

    /**
     * @var StoreRepositoryInterface $storeRepository
     */
    protected $storeRepository;

    /**
     * @var ProductRepositoryInterface
     */
    protected $productRepository;

    /**
     * @var ImageContentValidatorInterface
     */
    protected $contentValidator;

    /**
     * @var ProductAttributeMediaGalleryManagementInterface
     */
    protected $galleryManagement;

    /**
     * @param StoreRepositoryInterface $storeRepository
     * @param ProductAttributeMediaGalleryManagementInterface $galleryManagement
     * @param ProductRepositoryInterface $productRepository
     * @param ImageContentValidatorInterface $contentValidator
     */
    public function __construct(StoreRepositoryInterface $storeRepository, ProductAttributeMediaGalleryManagementInterface $galleryManagement, ProductRepositoryInterface $productRepository, ImageContentValidatorInterface $contentValidator) {
        $this->productRepository = $productRepository;
        $this->contentValidator = $contentValidator;
        $this->galleryManagement = $galleryManagement;
        $this->storeRepository = $storeRepository;
    }

    /**
     * @inheritdoc
     */
    public function update($skus, ProductAttributeMediaGalleryEntryInterface $entry) {
        $sku_array = explode('|', $skus);

        foreach ($sku_array as $sku) {
            $this->galleryManagement->create($sku, $entry);
        }
    }

(...)

}

1) I need to mock a product, I've already did that, but then all attributes are NULL, so I would need to set an SKU at least. setData is not working. I'm stuck here.

I did this:

/**
* @var \Magento\Catalog\Model\Product
*/
protected $product;

protected function setUp() {
    $this->product = $this->createMock(\Magento\Catalog\Model\Product::class, [], [], '', false);

    $this->product->setSku('test');
    var_dump($this->product->getSku()); //returns NULL

    $this->product->setData('sku', 'test');
    var_dump($this->product->getData('sku')); //returns NULL

    $this->product->save();
    var_dump($this->product->getData('sku')); //returns NULL
 }

2) Then I get my model and call my method passing this SKU and a fixed entry as a parameters.

3) Verify the product has this entry.

By the way, I'm very new at unit testing and on Magento too.

2
  • can you also post the method you are trying to test? maybe the full class you are testing?
    – Marius
    Commented Dec 22, 2016 at 16:43
  • I added my class
    – Marc Pont
    Commented Dec 22, 2016 at 17:04

2 Answers 2

3

Use $product->method('getSku')->willReturn('test'); Mocks can be configured in many ways! It is worth reading the documentation here: https://phpunit.de/manual/current/en/test-doubles.html

4
  • But doing this will not help at the next step, I think. I want to call the function update passing an sku as parameter. I need that sku is associated at this product
    – Marc Pont
    Commented Dec 22, 2016 at 17:03
  • I think you really want to write an integration test using real objects instead of a unit test.
    – Vinai
    Commented Dec 22, 2016 at 17:05
  • Well I don't know, all I need is a product that could do this functionality about adding an entry object inside it and verify that entry is correct. Can't do that a mock object?
    – Marc Pont
    Commented Dec 22, 2016 at 17:31
  • 3
    if you need "real" product functionality, you really might need an integration test. You might want to have a look at how to create fixtures in m2. devdocs.magento.com/guides/v2.0/mtf/mtf_entities/… It allows you to create a product object just for your test and then test against it's functionalities Commented Dec 22, 2016 at 19:34
0

I believe it will be less complicated if we could separate the required logic to test in different methods and test that specific method using the PHPUnit framework when doing the TDD development.

For example, in your method update(), I can see two sections.

Section 1:

$sku_array = explode('|', $skus);

Section 2:

foreach ($sku_array as $sku) {
   $this->galleryManagement->create($sku, $entry);
}

So if you would need to add a unit test for section one, you can create a separate method called getExplodedSkus() for that section and use assertEquals() method (compare exploded array values) in PHPUnit. For section two, you can create another method called createGalleryItem() and use assertInstanceOf() method (verify $sku_array has product type objects) in PHPUnit.

FYI: PHP variable names have to be camelCase and not the snake_case. $sku_array should be $skuArray.

Hope this will help to make it less complex.

Cheers!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.