Модульный тест для функций репозитория в Magento 2


У меня есть класс, использующий Magento 2 AttributeRepository. Могу ли я написать модульный тест для своего класса, который получает атрибут на основе кода атрибута?

namespace Company\Catalog\Test\Unit\Model;


use Company\Catalog\Helper\LandingPage;
use Company\Catalog\Model\Brand;
use Magento\Eav\Model\AttributeRepository;
use Magento\Store\Model\StoreManagerInterface;

class BrandTest extends \PHPUnit_Framework_TestCase
{
    /** @var  Brand */
    private $brand;

    /** @var  AttributeRepository */
    private $attributeRepository;

    /** @var  StoreManagerInterface */
    private $storeManager;

    /** @var  LandingPage */
    private $landingPageHelper;

    protected function setUp()
    {
        $this->landingPageHelper = $this->getMockBuilder(LandingPage::class)
            ->disableOriginalConstructor()
            ->getMock();
        $this->attributeRepository  = $this->getMockBuilder(AttributeRepository::class)
            ->disableOriginalConstructor()
            ->getMock();
        $this->storeManager = $this->getMockBuilder(StoreManagerInterface::class)
            ->disableOriginalConstructor()
            ->getMock();

        $this->landingPageHelper
            ->method('getBrandAttributeCode')
            ->willReturn('brands');

        $this->brand = new Brand($this->storeManager, $this->attributeRepository, $this->landingPageHelper);
    }

    public function testGetBrandAttributeCode()
    {
        $expected = 'brands';
        $this->assertEquals($expected, $this->brand->getBrandAttributeCode());
    }

    public function testGetBrandAttribute()
    {
        $expected = 'brands';
        $attribute = $this->brand->getBrandAttribute($expected);
        echo $attribute->getAttributeCode();
        $this->expectOutputString($expected);
    }
}

Должен ли я даже подготовить макет данных для хранилища или я могу получить фактическое значение из базы данных с помощью AttributeRepository?

Author: Fabian Schmengler, 2017-02-15

1 answers

Должен ли я вообще подготовить макет данных для репозитория или я могу получить фактическое значение из базы данных с помощью атрибута?

Это решение между модульными тестами и интеграционными тестами.

  • Интеграционные тесты проверяют реальное взаимодействие с Magento и попадают в базу данных. Эти тесты полезны для доказательства того, что ваш код (все еще) работает вместе с платформой и другими компонентами, а также для поиска регрессии.

  • Модульные тесты тестируют ваш код изолированно и не должны использовать реальное хранилище. Эти тесты полезны при разработке на основе тестов для руководства вашим дизайном, они могут быстро протестировать вашу бизнес-логику во всех крайних случаях.

Для модульных тестов класса, использующего репозиторий ядра, вы получите сложную настройку макета. Это возможно, и я сделал это для хранилищ атрибутов, но лучший подход - избавиться от комплекса зависимость и оставьте ее в тонкой оболочке (для которой нужны только интеграционные тесты)

Я написал об этой теме здесь: Что нужно высмеивать в модульном тесте Magento 2

"Только макетные типы, которыми вы владеете" [...] не следует воспринимать как строгое правило, иначе вы окажетесь в другой крайности, имея обертки поверх обертки для всего. Но это может быть чрезвычайно полезно для упрощения API и адаптируйте его к вашим потребностям.

Упрощение сложного API

Вот возможная оболочка для хранилища продуктов, если вам нужно найти продукты по производителю:

interface ProductRepository
{
    /**
     * @api
     * @return ProductInterface[]
     */
    public function productsByManufacturer($manufacturer);
}

Там нет критериев поиска и нет результата поиска. Его легче высмеивать , а также проще использовать. Вызывающий код интересует только производителя и продукты, мы оставляем детали фреймворка в реализации нашей оболочки.

Вы можете спросить, как протестировать эту обертку. Ответ заключается в том, что он должен быть протестирован с помощью интеграционных тестов всего особенность, без насмешек. Модульный тест для этого не имеет смысла.

Если ваш класс Brand не более чем извлекает атрибут бренда, у вас уже есть обертка. Не тратьте время на модульные тесты для этого и вместо этого пишите интеграционные тесты. В других классах, которые используют Brand, вы можете легко имитировать Brand и вам не нужно заботиться о хранилище атрибутов.

 1
Author: Fabian Schmengler, 2017-02-17 00:48:53