Skip to content

Instantly share code, notes, and snippets.

@ludofleury
Last active December 15, 2015 18:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ludofleury/5304938 to your computer and use it in GitHub Desktop.
Save ludofleury/5304938 to your computer and use it in GitHub Desktop.
atoum mock example
<?php
namespace MyLittle\Bundle\BoxBundle\Validator\Constraints;
use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Doctrine\Common\Persistence\ManagerRegistry;
use MyLittle\Bundle\BoxBundle\Model\ProductInterface;
use DomainException;
use InvalidArgumentException;
/**
* Ensure the SKU uniqueness for a product
*/
class StockValidator extends ConstraintValidator
{
/**
* @var ManagerRegistry
*/
private $registry;
/**
* @param ManagerRegistry $registry
*/
public function __construct(ManagerRegistry $registry)
{
$this->registry = $registry;
}
/**
* {@inheritDoc}
*/
public function validate($product, Constraint $constraint)
{
if (!is_object($product)) {
throw new InvalidArgumentException(sprintf('The data is not an object'));
}
if (!$product instanceof ProductInterface) {
throw new DomainException(sprintf('The class "%s" must implement ProductInterface', get_class($product)));
}
$className = $this->context->getClassName();
$repository = $this->registry->getRepository($className);
$result = $repository->findBy(['sku' => $product->getSku()]);
if (1 < count($result) ||
(1 === count($result) && $product !== ($result instanceof \Iterator ? $result->current() : current($result)))) {
$this->context->addViolationAt('sku', 'The reference is already used.');
}
}
}
<?php
namespace MyLittle\Bundle\BoxBundle\Tests\Units\Validator\Constraints;
use atoum\AtoumBundle\Test\Units;
use MyLittle\Bundle\BoxBundle\Validator\Constraints;
use Mock;
class StockValidator extends Units\Test
{
protected $context;
protected $validator;
public function beforeTestMethod($method)
{
$this->context = $this->mockExecutionContext();
$registry = $this->mockManagerRegistry();
$this->validator = new Constraints\StockValidator($registry);
$this->validator->initialize($this->context);
}
public function testNullIsInvalid()
{
$validator = $this->validator;
$this
->exception(
function () use ($validator) {
$validator->validate(null, new Constraints\Stock());
}
)
->isInstanceOf('\InvalidArgumentException')
->hasMessage('The data is not an object')
;
}
public function testObjectIsInvalid()
{
$validator = $this->validator;
$this
->exception(
function () use ($validator) {
$validator->validate(new \stdClass, new Constraints\Stock());
}
)
->isInstanceOf('\DomainException')
->hasMessage('The class "stdClass" must implement ProductInterface')
;
}
public function testNonUniqueSkuIsInvalid()
{
$registry = $this->mockManagerRegistry();
$registry->getMockController()->getRepository = function ($className) {
$repository = new Mock\Doctrine\Common\Persistence\ObjectRepository();
$repository->getMockController()->findBy = [new Mock\MyLittle\Bundle\BoxBundle\Model\ProductInterface()];
return $repository;
};
$this->validator = new Constraints\StockValidator($registry);
$this->validator->initialize($this->context);
$product = new Mock\MyLittle\Bundle\BoxBundle\Model\ProductInterface;
$validator = $this->validator;
$this->validator->validate($product, new Constraints\Stock());
$this
->mock($this->context)
->call('addViolationAt')
->withArguments('sku', 'The reference is already used.')
->once()
;
}
/**
* If the repository return an empty array, it means the current checked sku is new & unique
*/
public function testNewUniqueSkuIsValid()
{
$product = new Mock\MyLittle\Bundle\BoxBundle\Model\ProductInterface;
$validator = $this->validator;
$this->validator->validate($product, new Constraints\Stock());
$this
->mock($this->context)
->call('addViolationAt')
->never()
;
}
/**
* If the repository return an array with only 1 result, and the result is the same
* object than the currently checked, the sku still unique.
*/
public function testUniqueSkuIsValid()
{
$product = new Mock\MyLittle\Bundle\BoxBundle\Model\ProductInterface;
$registry = $this->mockManagerRegistry();
$registry->getMockController()->getRepository = function ($className) use ($product) {
$repository = new Mock\Doctrine\Common\Persistence\ObjectRepository();
$repository->getMockController()->findBy = [$product];
return $repository;
};
$this->validator = new Constraints\StockValidator($registry);
$this->validator->initialize($this->context);
$validator = $this->validator;
$this->validator->validate($product, new Constraints\Stock());
$this
->mock($this->context)
->call('addViolationAt')
->never()
;
}
/**
* Mock a Symfony validation execution context
*
* @return Mock\Symfony\Component\Validator\ExecutionContext
*/
private function mockExecutionContext()
{
$globalContext = new Mock\Symfony\Component\Validator\GlobalExecutionContextInterface();
$globalContext->getMockController()->getViolations = new Mock\Symfony\Component\Validator\ConstraintViolationList();
$translator = new Mock\Symfony\Component\Translation\TranslatorInterface();
return new Mock\Symfony\Component\Validator\ExecutionContext($globalContext, $translator);
}
/**
* Mock a Doctrine manager registry context
*
* @return Mock\Doctrine\Common\Persistence\ObjectRepository
*/
private function mockManagerRegistry()
{
$registry = new Mock\Doctrine\Common\Persistence\ManagerRegistry();
$registry->getMockController()->getRepository = function ($className) {
$repository = new Mock\Doctrine\Common\Persistence\ObjectRepository();
$repository->getMockController()->findBy = [];
return $repository;
};
return $registry;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment