Модульный тест для функций репозитория в 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
?
1 answers
Должен ли я вообще подготовить макет данных для репозитория или я могу получить фактическое значение из базы данных с помощью атрибута?
Это решение между модульными тестами и интеграционными тестами.
Интеграционные тесты проверяют реальное взаимодействие с Magento и попадают в базу данных. Эти тесты полезны для доказательства того, что ваш код (все еще) работает вместе с платформой и другими компонентами, а также для поиска регрессии.
Модульные тесты тестируют ваш код изолированно и не должны использовать реальное хранилище. Эти тесты полезны при разработке на основе тестов для руководства вашим дизайном, они могут быстро протестировать вашу бизнес-логику во всех крайних случаях.
Для модульных тестов класса, использующего репозиторий ядра, вы получите сложную настройку макета. Это возможно, и я сделал это для хранилищ атрибутов, но лучший подход - избавиться от комплекса зависимость и оставьте ее в тонкой оболочке (для которой нужны только интеграционные тесты)
Я написал об этой теме здесь: Что нужно высмеивать в модульном тесте Magento 2
"Только макетные типы, которыми вы владеете" [...] не следует воспринимать как строгое правило, иначе вы окажетесь в другой крайности, имея обертки поверх обертки для всего. Но это может быть чрезвычайно полезно для упрощения API и адаптируйте его к вашим потребностям.
Упрощение сложного API
Вот возможная оболочка для хранилища продуктов, если вам нужно найти продукты по производителю:
interface ProductRepository { /** * @api * @return ProductInterface[] */ public function productsByManufacturer($manufacturer); }
Там нет критериев поиска и нет результата поиска. Его легче высмеивать , а также проще использовать. Вызывающий код интересует только производителя и продукты, мы оставляем детали фреймворка в реализации нашей оболочки.
Вы можете спросить, как протестировать эту обертку. Ответ заключается в том, что он должен быть протестирован с помощью интеграционных тестов всего особенность, без насмешек. Модульный тест для этого не имеет смысла.
Если ваш класс Brand
не более чем извлекает атрибут бренда, у вас уже есть обертка. Не тратьте время на модульные тесты для этого и вместо этого пишите интеграционные тесты. В других классах, которые используют Brand
, вы можете легко имитировать Brand
и вам не нужно заботиться о хранилище атрибутов.