I have JSDoc defined method.
/**
* #memberOf cy
* #method slotContent
*/
If I use this method directly, then WebStorm detect documentation correctly.
cy.slotContent()
But, if I call this method in chainable, then WebStorm is not detect JSDoc...
cy
.get()
.find()
.slotContent()
What I do wrong?
Watch how they do it in JSdoc website, https://jsdoc.app/tags-memberof.html
Related
I'm using PhpUnit/DbUnit to create a set of 5 to 10 fixture records. I use in-memory sqlite.
I successfully can use a Doctrine\DBAL\Connection to access it, so I can use methods like ->insert( $tableName, $data ); for my tests.
Now I want to consume the Doctrine EntityManager so I can create an entity and call ->persist().
In unit-testing I used to mock the EntityManager and asserted an expectation to call persist.
But for functional-testing I want to check the final result written to the DB, even go further and re-use the result of the writing.
I therefore need to create a real EntityManager but consuming the DbUnit connection.
I've seen that creting a new EntityManager takes 3 arguments, but still the creator is protected:
/**
* Creates a new EntityManager that operates on the given database connection
* and uses the given Configuration and EventManager implementations.
*
* #param \Doctrine\DBAL\Connection $conn
* #param \Doctrine\ORM\Configuration $config
* #param \Doctrine\Common\EventManager $eventManager
*/
protected function __construct(Connection $conn, Configuration $config, EventManager $eventManager)
{
[...]
I don't know if I'm expected to create a subclass, or maybe use an already subclassed EntityManager or how should I proceed.
So question:
How can I setup a real Doctrine\ORM\EntityManager within a PhpUnit/DbUnit test class using the low level Doctrine\Dbal\Connection that is already bound to the DbUnit connection?
Note: I'm inside a symfony3 project, so mapping files are in the expected places of symfony.
Symfony 2.8 + doctrine
I have two Bundles: CoreBundle and BonusBundle
CoreBundle have folder Model containing abstract class ClassA:
use Doctrine\ORM\Mapping as ORM;
//[...]
abstract class ClassA
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
protected $name;
}
and in another directory Entity - ClassB:
//[...]
/**
* ClassB
*
* #ORM\Table()
* #ORM\Entity
*/
class ClassB extends ClassA
{
/**
* #var integer
*
* #ORM\Column(name="id", type="integer")
* #ORM\Id
* #ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
}
Currently this working well, ClassB inherit name property and this way we have mapped Entity ClassB with id and name.
I added in Model directory of BonusBundle (second one) other abstract class ClassC. Its the same as ClassA but in other bundle.
And now last key thing to my example - I added ClassD in CoreBundle (Entity directory) extending ClassC from BonusBundle (the same way as above).
My problem
In result I recived ClassB with properties id, name and ClassD only with id property.
I cannot understand why this happen. Its looks like doctrine ignore annotations if superclass lives in other Bundle. I checked some docs and other questions but I can't find understand what happening.
I see in config docs here that auto_mapping option checking Entity directory:
Doctrine's auto_mapping feature loads annotation configuration from
the Entity/ directory of each bundle and looks for other formats (e.g.
YAML, XML) in the Resources/config/doctrine directory.
and
If it wasn't possible to determine a configuration format for a
bundle, the DoctrineBundle will check if there is an Entity folder in
the bundle's root directory. If the folder exist, Doctrine will fall
back to using an annotation driver.
in my project this folder exist in both Bundles. And If symfony check only Entity folder then why first example (Model) working well?
How this mechanism works?
I tested some possibilities and I found solution to fix it but still no idea why this happen.
If I add annotation to superclass #ORM\MappedSuperclass() then mappings are loaded correctly but only if class is located in Entity directory.
use Doctrine\ORM\Mapping as ORM;
/**
* ClassA
*
* #ORM\MappedSuperclass()
*/
abstract class ClassA
{
/**
* #var string
*
* #ORM\Column(name="name", type="string", length=255)
*/
protected $name;
}
This way my annotations are visible in other Bundles and my ClassA is not Entity itself.
Still I dont understand why it works if class exist in the same Bundle but in other directory. In addition inside FoSUserBundle exist similar example using MappedSuperclass() - FOSUserBundle/Model/User.php but its located in Model directory and still working.
//EDIT
Completion to #Boulzy answer
Probably i found answer for second part - why it can see mapping from other directory but the same bundle. After analysing other working example I found that mapped property with strict access private is not visible for child class but protected property is visible, mapped and don't need #ORM\MappedSuperclass() annotation as long as it used in the same Bundle.
It seems that #ORM\MappedSuperclass() give us possibility to map even private properties and this way they are visible and mapped for other classes in any other bundle (as long as it lives in Entity or other mapped directory).
In completion of #Griva answer about the MappedSuperClass, here is an simple example of how to tell Doctrine to look for mapped classes in other folders than Entity:
<?php
namespace AppBundle;
use Doctrine\Bundle\DoctrineBundle\DependencyInjection\Compiler\DoctrineOrmMappingsPass;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class AppBundle extends Bundle
{
/**
* {#inheritDoc}
*/
public function build(ContainerBuilder $container)
{
parent::build($container);
// With Yaml configuration format
$container->addCompilerPass(DoctrineOrmMappingsPass::createYamlMappingDriver(array(
realpath(__DIR__ . '/Resources/config/doctrine-mapping') => 'AppBundle\Model'
)));
// With annotation configuration format
$container->addCompilerPass(DoctrineOrmMappingsPass::createAnnotationMappingDriver(array(
'AppBundle\Model'
)));
}
}
There are Doctrine MappingsPass available for MongoDB and CouchDB too.
i have just implemented my first service in Symfony2.
I noticed that, within a controller method, whether i call the service so
$this->container->get('main.service');
or so
$this->get('main.service');
there is no difference.
I get the service equally with both.
Where are the differences?
There's no difference if you're extending the Base Controller provided by Symfony.
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
class YourController extends Controller
If you take a deeper look at the implementation of the Symfony\Bundle\FrameworkBundle\Controller\Controller, you may notice that it provides a get() helper which do exactly the same call as what you did first (getting your service through the container).
So, then,
There's no difference as $this->get('something') simply sencapsulates a call to $this->container->get('something').
Here's the implementation of the get() method you're calling when doing $this->get('main.service');
/**
* Gets a service by id.
*
* #param string $id The service id
*
* #return object The service
*/
public function get($id)
{
return $this->container->get($id);
}
I'm creating a simple RESTful API in PHP for practice. I'm trying to write as testable code as possible. After reading many tutorials and watching a few videos, I still feel at a loss on how to design this.
Basically, I have set up a Router class. It is responsible for mapping url paths to controller methods.
It's easy to test the router's state after adding a route.
But, how do I test if the proper class->function(params) has been called in respond()?
I'm using PHPUnit, and I've been reading about mocks. I don't know how to use them in this context.
Currently, respond() parses a given path and request method, and calls the mapped method.
Here is my current design:
private $routes;
public function __construct() {
$routes = array();
}
/**
* Gets all current routes
*/
public function getRoutes();
/**
* Sets all routes
*/
public function setRoutes($routes);
/**
* Routes GET request
*/
public function get();
/**
* Routes POST request
*/
public function post();
/**
* Routes PUT request
*/
public function put();
/**
* Routes DELETE request
*/
public function delete();
/**
* Sets up default paths for a given resource
*/
public function resource();
/**
* Respond to request
* #return mixed JSON of resource data
*/
public function respond($req_method, $request);
/**
* Returns mapped call info from request method and path
* #return mixed An array of the call and params
*/
private function parse($req_method, $request);
As the comments have indicated, this would be a good use of a spy or mocking system. PHPunit has some ability to create and test for mocks, but I prefer to use a different library - Mockery.
This code will create a class and test that that when you call average(), it's called three times, and then also returns a given value.
Your code would call respond(), after setting up a mock that shouldReceive('get')->once() (for example). The m::close in the teardown will verify that get() was called, just one time, and would fail the test if it was not.
<?php
use \Mockery as m;
class TemperatureTest extends PHPUnit_Framework_TestCase
{
public function tearDown()
{
m::close();
}
public function testGetsAverageTemperatureFromThreeServiceReadings()
{
$service = m::mock('service');
$service->shouldReceive('readTemp')->times(3)->andReturn(10, 12, 14);
$temperature = new Temperature($service);
$this->assertEquals(12, $temperature->average());
}
}
Since you would be calling a real class to do work in respond(), you will need a 'partial mock'
$restful= m::mock('RestfulController[get]');
$restful->shouldReceive('get')->once();
You can implement step definitions for undefined steps with these snippets:
/**
* #Given /^people enter (\d+)$/
*/
public function peopleEnter($argument1)
{
throw new Pending();
}
Should I put it under bootstrap.php? I'm really confused what should I do know...
I want to use the oop style, not closures.
I'm new to BDD and Behat.
Any help is welcome.
Thanks
Yes, put it in the Bootstrap. By default, Behat looks for bootstrap/FeatureContext.php as its bootstrap file, but these methods should go into whatever bootstrap class you're using that extends BehatContext.