Download the PHP package jsiefer/mage-mock without Composer
On this page you can find all versions of the php package jsiefer/mage-mock. It is possible to download/install these versions without Composer. Possible dependencies are resolved automatically.
Informations about the package mage-mock
mage-mock
Creating UnitTests for Magento classes can be hard considering that you have to extend from so many classes which in term require a lot of setup to get initialised in the first place.
The framework mocker will help you to mock the Magento environment.
The idea for a UnitTest here is that it...
- ...should run quickly (<100ms)
- ...no Magento installation or source is required
All required Magento Classes are generated on the fly by the class-mocker lib.
Setup
Simply load this project using composer:
composer require jsiefer/mage-mock
Create a PHPUnit bootstrap.php
file and register the MagentMock to
the ClassMocker and enable the ClassMocker.
It is also recommended to setup the ClassMocker test listener so
ClassMock object assertions are validated as well.
(e.g. $test->expects($this->once())->method('test')
)
Same goes for the the MageMock listener, which will reset the Mage class automatically after each test.
Just add listener to your phpunit.xml
How it works
The mocked classes
All classes generated by the class-mocker implement the PHPUnit MockObject interface
that lets you alter or assert certain behaviour during runtime as you are familiar
when using the standard PHPUnit mocks (e.g. $moock->expects($this->once())...
).
Additional fixed behaviour, like simple stub logic, valid for the entire test run can be defined using traits.
MageMock already provides some basic stub logic. So for instance calling save()
method on
a Model will trigger the _beforeSave()
and _afterSave()
method.
Traits are used and registered to Mocks, when calling a Method on any generated Mock,
the trait method is not getting called straight away, instead the call gets handled by
the BaseMock
class which is base class for all generated Mocks. The BaseMock
will then
check for any defined methods in the following order:
-
Check for any mocked method.
-
Check for closure functions.
-
Check for trait methods.
-
Check for and call magic trait methods (e.g.
__call()
)The above traits can use
___call()
method to listen to any call. -
Default method call (return self)
Can be changed to return NULL or throw an exception.
The Mage class problem
One of the main challenges during unit testing in Magento is the Mage class. Mocking the behavior of the static Mage class for tests is not straight forward.
To solve this issue, two Mage classes are created. One called the MageFacade-class, which is used for the Mage class to fetch all static calls and delegate it to the MageClass-class, however the MageClass is not static but as well an auto-generated mock that is re-initialized for each test.
This way, we can not only bind trait stubs to the Mage class but also alter the behavior of the Mage class on runtime using the same methods described above.
(See testMockingMage()
below)
Another problem is that no configuration XML is available for the unit test, so resolving
model names like customer/session
needs to be handled in a semi-automated way.
A name resolver can be set to the MageFacade class which will try its best to resolve any given name. You can register your own namespaces there, or create your own name resolver.
(See testSingleton()
below)
Further Examples
Suppose you have the following model:
Now lets write a unit test for this class, remember you only want to test your logic. The magento logic of the parent class is not relevant at this point.
The mage-mocker however helps you by implementing some of the most important classes and methods, like the Varien_Object implementation.
All Mage_*
and Varien_*
classes are created and extended on the
fly when running the test. They will have no method implementation,
however they all implement the correct class hierarchies and class
constants.
e.g:
Magemock_Sample_Model_Vehicle
- extends:
Mage_Core_Model_Abstract
- extends:
Varien_Object
- implements:
ArrayAccess
Lets look at a simple test for the above example.
Since this is a UnitTest only focusing on your class no Magento initialization process is required and the test can run in a few milliseconds.
Note
This is still an early release and a proof of concept. It yet needs to be tested if this approach can be of use. If you have any ideas, feedback or issues let me know.