phpunit mockery No matching handler found - phpunit

When I try to execute phpUnit with multiple test, someone fails with this output:
No matching handler found [...] Either the method was unexpected or its arguments matched no expected argument list for this method.
But if I execute the test alone, pass without errors. How I force to use different Mockery object in each test?
EDITED:
If I run phpunit separately, works fine and all test passed, but if I use the directory which contains the 2 classes... the 1st method passed but the second throw me this exception.
I have this method in the class AddCountryTest:
public function testAddCountry()
{
$name = 'test testAddCountryCommand';
$iso = 'derd';
$telPrefix = '+34 5';
$languageId = 1;
/* #var WtsCqrsRequest $wtsCqrsRequest */
$wtsCqrsRequest = \Mockery::mock('Wts\Country\App\Cqrs\Country\Request\AddCountryRequest')->makePartial();
/** #noinspection PhpUndefinedMethodInspection */
$wtsCqrsRequest
->shouldReceive('getIso')->andReturn($iso)
->shouldReceive('getTelPrefix')->andReturn($telPrefix)
->shouldReceive('getName')->andReturn($name)
->shouldReceive('getDefaultLanguageId')->andReturn($languageId)
;
$commandHandler = $this->getCommandHandler($wtsCqrsRequest);
/* #var Country $country */
$country = $commandHandler->handle($wtsCqrsRequest);
$this->assertEquals($country->getIso(), $iso);
}
and this one in the class ReadCountryTest:
public function testReadCountry()
{
$name = 'test testAddCountryCommand';
$iso = 'zzz';
$telPrefix = '+34 5';
$languageId = 1;
$this->createCountry($name,$iso,$telPrefix,$languageId);
$iso = 'aaa';
$this->createCountry($name,$iso,$telPrefix,$languageId);
$iso = 'vvv';
$this->createCountry($name,$iso,$telPrefix,$languageId);
//Read
/* #var WtsCqrsRequest $wtsCqrsRequest */
$wtsCqrsRequest = \Mockery::mock('Wts\Country\App\Cqrs\Country\Request\ReadCountriesRequest')->makePartial();
$commandHandler = $this->getCommandHandler($wtsCqrsRequest);
/** #var WtsCqrsResponse $wtsCqrsResponse */
$wtsCqrsResponse = $commandHandler->handle($wtsCqrsRequest);
/* #var CountryDto[] countries */
$countries = $wtsCqrsResponse->getData();
/** #var CountryDto $countryRead */
$this->assertEquals(count($countries), 3);
}
Thanks

I had the same problem and I know this question is almost 7 years old but it's the first result that appeared on Google, so...
If the individual test works but if several of them run at the same time fails it is because you need to either manually reset Mockery or to implement the MockeryTestCase,
http://docs.mockery.io/en/latest/reference/phpunit_integration.html
After that, all the tests would work as expected.

Related

Elegant way to add or remove new and old categories with PersistCollection

What I did is pretty ugly. It works but is there any "Elegant" way of doing this in symfony ? Couldn't find something useful in the documentation by myself. What I did is:
/**
* #var PersistentCollection $currentCategories
*/
$currentCategories = $product->getCategories();
/**
* #var array $requestCategories
*/
$requestCategories = $request->getCategories();
foreach ($currentCategories as $category) {
$oldCategoryIds[] = $category->getId();
}
$forRemove = array_diff($oldCategoryIds, $requestCategories);
$forSave = array_diff($requestCategories, $oldCategoryIds);
Is there a way to compare the ids in the requestedCategories for such that miss in the oldCategoryIds and remove them from the DB. The DB can handle by myself.
Don't think there's an out-of-the-box "elegant" approach to this. But an alternative approach could be:
/** #var Collection<Category> $removedCategories */
$removedCategories = $currentCategories->filter(
function (Category $category) use ($requestCategories) {
return false === in_array($category->getId(), $requestCategories, true);
}
);

SonataMediaBundle Type error when trying to delete the link with media

i have project that uses sonataAdmin and sonataMedia
when i tried to delete the image using the check box provided by the bundle
click to see image
i get this error :
Type error: Argument 1 passed to BackBundle\Entity\reference::setMedia() must implement interface Sonata\MediaBundle\Model\MediaInterface, null given, called in /home/hichem/PhpstormProjects/sifastProject/vendor/symfony/symfony/src/Symfony/Component/PropertyAccess/PropertyAccessor.php on line 591
it appears exactly here:
Stack Trace
in src/BackBundle/Entity/reference.php at line 69 -
/**
* #param MediaInterface $media
*/
public function setMedia(MediaInterface $media)
{
$this->media = $media;
}
from what i've understand(or at least think so)the setter can't set the value with null
if any one know what's the problem please help
Because you have no selected file I think that this will help you:
/**
* #param MediaInterface $media
*/
public function setMedia(MediaInterface $media = null)
{
$this->media = $media;
}

Symfony Validation dependent on another property

Trying to validate if one field is not empty (length > 0) then the length of the field being validated must be a certain length (2 characters). It seems like an "Assert\Expression" might work in this situation but I am having trouble trying to find the length of the properties. It seems like you cannot call php functions within the Expression. The expression documentation mentions functions but maybe I do not understand it... Do I need to register my own function that simply return a strlen(). If so how do you register your own functions? Can someone explain if there is a way to do this, or maybe there is a better way than using Expression that I am overlooking...
/**
* #var string
*
* #ORM\Column(name="plate", type="string", length=10)
*/
private $plate;
/**
* #var string
*
* #ORM\Column(name="state", type="string", length=2)
* #Assert\Expression(
* "strlen(this.getPlate()) == 0 or (strlen(this.getPlate()) > 0 and strlen(value) == 2)",
* message="Must be 2 characters"
* )
*/
private $state;
In the above case I get an error The function "strlen" does not exist around position 1
Looks like you will need to register your own function. Have a look at the docs: https://symfony.com/doc/current/components/expression_language/extending.html#registering-functions
There is an example on lowercase, strlen should be very similar.
EDIT:
You can also use a callback validator.
/**
* #Assert\Callback()
*/
public function validateState(ExecutionContextInterface $context)
{
if (!empty($this->plate) && mb_strlen($this->state) !== 2) {
$context->buildViolation('State must be 2 characters long')
->atPath('state')
->addViolation();
}
}
But if you are planning to using this kind of validation in multiple places, you can write and register your own validator.

How to show content of a custom block using PHP code format in Drupal 8

I have added some custom code in a block using PHP code format to show that block on a specific page. I have checked all the things working fine on Devel PHP page but contents are not showing on page. The code below fetches the field value of a destination node.
$refer = $_SERVER[HTTP_REFERER];
$parsed = parse_url($refer);
$alias = array_pop($parsed);
$dst = \Drupal::service('path.alias_manager')->getPathByAlias($alias , $langcode);
$nid = array_pop(explode('/', $dst));
$dest_node = node_load($nid);
$body = $dest_node->get('body')->getValue();
print $body; //have tried other printing methods also but invain
Hope this clarifies the question.
Thanks
Are you sure that it works in Devel? I've just tried to execute your code, and this line:
$body = $dest_node->get('body')->getValue();
returns Array.
Try to use this one instead:
$body = $dest_node->body->value;
First of all, your first block of code (getting current node) can be replaced with just one line:
$node = \Drupal::service('current_route_match')->getParameter('node');
And the whole block can be changed in the following way:
if ($node = \Drupal::service('current_route_match')->getParameter('node')) {
print $node->body->value;
}
P.S. And it's definitely a bad idea to use PHP text filter. You may easily write your own custom module providing required block. The simplest block plugin requires several lines of code:
/**
* #file
* Contains \Drupal\my_module\Plugin\Block\MyBlock.
*/
namespace Drupal\my_module\Plugin\Block;
use Drupal\Core\Block\BlockBase;
/**
* Provides my super block.
*
* #Block(
* id = "my_module_block",
* admin_label = #Translation("My Block"),
* category = #Translation("My Module"),
* )
*/
class MyBlock extends BlockBase{
/**
* Builds and returns the renderable array for this block plugin.
*
* #return array
* A renderable array representing the content of the block.
*
* #see \Drupal\block\BlockViewBuilder
*/
public function build() {
if ($node = \Drupal::service('current_route_match')->getParameter('node')) {
return [ '#markup' => $node->body->value ];
}
}
}
This file MyBlock.php must be placed in /src/Plugin/Block/ directory inside your custom module named my_module.

Unable to retrieve records using a variable in Symfony2, but works if I don't use a variable?

I have three SQL statements in Symfony2, and they all use a variable that contains the record ID (which is passed through using the URL). The first SQL statement works correctly, however, the other two don't. They often result in errors like this:
An exception occurred while executing 'SELECT m0_.name AS name0,
m0_.created AS created1, m0_.event_date AS event_date2,
m0_.description AS description3, m0_.event_type AS event_type4,
m1_.surname AS surname5, m1_.first_name AS first_name6 FROM map_lists
m0_ LEFT JOIN map_list_members m2_ ON (m2_.list_id = m0_.id) LEFT JOIN
map_contacts m1_ ON (m1_.id = m2_.contact_id) WHERE m0_.branch_id = ?
AND m0_.event_type IS NOT NULL AND m1_.id = ? ORDER BY m0_.event_date
DESC' with params {"1":"0","2":{}}:
Catchable Fatal Error: Object of class Doctrine\ORM\Query could not be
converted to string in
F:\wamp\www\centredb\vendor\doctrine\dbal\lib\Doctrine\DBAL\Connection.php
line 1211
The two SQL statements in question are:
// Retrieve Test For That Member
$membertests = $dm->createQuery('
SELECT mt.id, mt.taken, mt.result, mtd.test, mtd.description
FROM InstructorBundle:MapTests mt
LEFT JOIN InstructorBundle:MapTestDescriptions mtd WHERE mtd.id = mt.testDescription
WHERE mt.contact = :member'
)->setParameter('member', '40264');
$memtest = $membertests->getResult();
// Retrieve Events For That Member
$memberevents = $dm->createQuery('
SELECT mli.name, mli.created, mli.eventDate, mli.description, mli.eventType, mc.surname, mc.firstName
FROM InstructorBundle:MapLists mli
LEFT JOIN InstructorBundle:MapListMembers mlm WHERE mlm.list = mli.id
LEFT JOIN InstructorBundle:MapContacts mc WHERE mc.id = mlm.contact
WHERE mli.branch = :centre
AND mli.eventType IS NOT NULL
AND mc.id = :member
ORDER BY mli.eventDate DESC'
)->setParameters(array(
'centre' => $centreid,
'member' => $member
));
$memevent = $memberevents->getResult();
Now, if I remove $member from the Parameters and replace it with the record ID that I'm using during development these SQL statements work. Obviously this isn't ideal, so to find out why these SQL statements fail when using the same variable that the 3rd uses is vital.
The 3rd SQL statement, for reference, is:
// Retrieve Member Details
$member = $dm->createQuery('
SELECT mc.id, mc.surname, mc.firstName
FROM InstructorBundle:MapSubscriptions msu
LEFT JOIN InstructorBundle:MapContacts mc WHERE msu.contact = mc.id
LEFT JOIN InstructorBundle:MapFamilies mf WHERE mc.family = mf.id
WHERE mc.id = :member'
)->setParameter('member', $member);
I've looked at the Entity's of the two tables and the two fields that $member is used to recover the data from. They look like this:
MapTests mt
/**
* #var \MapContacts
*
* #ORM\ManyToOne(targetEntity="MapContacts")
* #ORM\JoinColumns({
* #ORM\JoinColumn(name="contact_id", referencedColumnName="id")
* })
*/
private $contact;
/**
* Set contact
*
* #param \Acme\InstructorBundle\Entity\MapContacts $contact
* #return MapTests
*/
public function setContact(\Acme\InstructorBundle\Entity\MapContacts $contact = null)
{
$this->contact = $contact;
return $this;
}
/**
* Get contact
*
* #return \Acme\InstructorBundle\Entity\MapContacts
*/
public function getContact()
{
return $this->contact;
}
MapContacts mc
/**
* #var integer
*
* #ORM\Column(name="id", type="integer", nullable=false)
* #ORM\Id
* #ORM\GeneratedValue(strategy="IDENTITY")
*/
private $id;
/**
* Get id
*
* #return integer
*/
public function getId()
{
return $this->id;
}
I can't figure it out, it seems fine to me. But obviously something is stopping this from working.
Is your $member variable an object? You need to use integer id as parameter in your query, so replace $member with $member->getId()
This is a really weird issue, as the $member variable works with one query but wouldn't with the other two. However, adding this code seemed to have fixed the issue:
$memberint = intval($member);
This seemed to fix it. The errors dissappeared. However, it doesn't explain really why $member will work with one query and not the other two.
I recommend use dsl, the query language provided by Doctrine. Your second query looks like:
$dm->createQuery()
->select('mli.name, mli.created, mli.eventDate, mli.description, mli.eventType, mc.surname, mc.firstName')
->from('InstructorBundle:MapLists', 'mli')
->leftJoin('mli.list', 'mlm')
->leftJoin('mlm.contact', 'mc')
->where('mli.branch = :centre')
->andWhere('mli.eventType IS NOT NULL')
->andWhere('mc.id = :member')
->orderBy('mli.eventDate', 'DESC')
->setParameters(array(
'centre' => $centreid,
'member' => $member
));
Look at examples here - http://docs.doctrine-project.org/en/latest/reference/dql-doctrine-query-language.html
Everywhere where id is used as a parameter, it is used as integer. And in database, id is always an integer. Doctrine needs your $member as an integer, whereas you are passing a numeric string. I assume that the portion of the code where Doctrine verifies parameters has some type of bug. I suggest that you report this bug at #doctrine channel on freenode.
As a solution for your code, just do typecasting for your $member variable either with intval($member) or (int)$member right in your query.

Resources