TL;DR:
I would love an example of how Magento\Framework\TestFramework\Unit\Helper\ObjectManager::getCollectionMock()
can be used for unit tests that involve collections and/or collection factories and a few words about how this works.
Long version
I'm trying to learn how to unit test my Magento 2 module.
I've reached the point where I need to test a class that has a dependency a collection factory.
So I need to mock this and return some dummy collection and I need a few items (can be 1) in this collection.
I found the method Magento\Framework\TestFramework\Unit\Helper\ObjectManager::getCollectionMock()
, but I think I'm not using it properly because I always get an empty collection.
My class looks like this:
<?php
namespace Sample\News\Model\Source;
use Magento\Framework\Option\ArrayInterface;
use Magento\Directory\Model\ResourceModel\Country\CollectionFactory as CountryCollectionFactory;
class Country implements ArrayInterface
{
/**
* @var CollectionFactory
*/
protected $countryCollectionFactory;
/**
* @var array
*/
protected $options;
/**
* constructor
*
* @param CountryCollectionFactory $countryCollectionFactory
*/
public function __construct(CountryCollectionFactory $countryCollectionFactory)
{
$this->countryCollectionFactory = $countryCollectionFactory;
}
/**
* get options as key value pair
*
* @return array
*/
public function toOptionArray()
{
if (is_null($this->options)) {
$this->options = $this->countryCollectionFactory->create()->toOptionArray(' ');
}
return $this->options;
}
/**
* @return array
*/
public function getOptions()
{
$countryOptions = $this->toOptionArray();
$_options = [];
foreach ($countryOptions as $option) {
$_options[$option['value']] = $option['label'];
}
return $_options;
}
}
My test code looks like this:
<?php
namespace Sample\News\Test\Unit\Model\Source;
use Magento\Framework\TestFramework\Unit\Helper\ObjectManager;
use Magento\Directory\Model\ResourceModel\Country\CollectionFactory;
use Magento\Directory\Model\ResourceModel\Country\Collection;
use Sample\News\Model\Source\Country;
class CountryTest extends \PHPUnit_Framework_TestCase
{
protected $objectManager;
protected $countryCollectionFactoryMock;
/**
* @var Country
*/
protected $countryList;
protected function setUp()
{
$this->objectManager = new ObjectManager($this);
$this->countryCollectionFactoryMock = $this->getMockBuilder(CollectionFactory::class)
->disableOriginalConstructor()
->getMock();
$countryMock = $this->getMockBuilder('\Magento\Directory\Model\Country')
->disableOriginalConstructor()
->getMock();
$countryMock->method('getId')->willReturn(1);
$countryMock->method('getTitle')->willReturn('Romania');
$collection = $this->objectManager->getCollectionMock(Collection::class, [$countryMock]);
$this->countryCollectionFactoryMock->method('create')->willReturn($collection);
$this->countryList = $this->objectManager->getObject(
Country::class,
[
'countryCollectionFactory' => $this->countryCollectionFactoryMock
]
);
}
public function testToOptionArray()
{
$this->assertEquals(['1' => 'Romania'], $this->countryList->toOptionArray());
}
}
My test fails saying that
null does not match expected type "array".
So I assume I'm using the getCollectionMock
method wrongly.
I don't actually need someone to debug my code (though it would be nice), I would accept an example on how to use getCollectionMock
and a few words about how it works.
Vinai
on the question.unit-tests
which should beVinai