Functional tests on Symfony 2 - issue with the default autoload.php.dist - symfony

I have been trying to run FunctionalTest which extends the Symfony\Bundle\FrameworkBundle\Tests\Functional\WebTestCase with not so much success.
The issue is that:
the code in FrameworkBundle\Tests\Functional\app\AppKernel.php attempts to load autoload.php.dist in the framework bundle (not the one in the app/).
And autoload.php.dist then tries to load vendor\autoload.php which does not exist within this path.
If I remove the autoload.php.dist in the FrameworkBundle then everything is fine, but I want to avoid doing that because each time I do composer update I will then have to remove that specific fine.
I wonder what I'm doing wrong.
The exact error from the console is posted below for your information:
Configuration read from D:\xampp\htdocs\demo\app\phpunit.xml.
dist
require_once() called at [D:\xampp\htdocs\demo\vendor\sym
fony\symfony\src\Symfony\Bundle\FrameworkBundle\Tests\Functional\app\AppKernel.p
hp:26]
require_once(D:\xampp\htdocs\demo\vendor\symfony\symfony\
src\Symfony\Bundle\FrameworkBundle\Tests\Functional\app\AppKernel.php)
called at
[D:\xampp\htdocs\demo\vendor\symfony\symfony\src\Symfony\Bun
dle\FrameworkBundle\Tests\Functional\WebTestCase.php:47]
Fatal error: main(): Failed opening required
'D:\xampp\htdocs\demo\vendor\symfony\symfony/vendor/autoload.php'
(include_path='.;D:\xampp\php\PEAR') in
D:\xampp\htdocs\demo\vendor\symfony\sym
fony\autoload.php.dist on line 9
The test class simply extends WebTestCase with the setUp looks like this:
static::$kernel = static::createKernel(array('test_case'));
static::$kernel->boot();
$this->containter = static::$kernel->getContainer();

Okay. I see the problem. You are extending from Tests\Functional\WebTestCase. That is actually a test for testing the WebTestCase. You want to extend from Test\WebTestCase.
use Symfony\Bundle\FrameworkBundle\Test\WebTestCase;
class PersonRepositoryTest extends WebTestCase
{
public function testProject()
{
$client = static::createClient();
$manager = $client->getContainer()->get('cerad_person.manager');
And you might want to get one or two working using the $client line shown above. All the setup stuff can be a bit tricky.

Related

Load Symfony (5.2) config from database

I am a newbie in Symfony but I know how to use OOP in PHP.
I try (with frustration) to couple custom parameters with Symfony configs by using Doctrine entities.
To solve the problem I used for e.g. the answer from Michael Sivolobov: https://stackoverflow.com/a/28726681/2114615 and other sources.
My solution:
Step 1: Create new package in config folder
-> config
-> packages
-> project
-> services.yaml
-> project
-> src
-> ParameterLoaderBundle.php
-> DependencyInjection
-> Compiler
-> ParameterLoaderPass.php
Step 2: Import the new resource
# config/services.yaml
...
imports:
- { resource: 'packages/project/config/services.yaml' }
...
Step 3: Package coding
# packages/project/config/services.yaml
services:
Project\:
resource: "../src"
<?php
namespace Project;
use Project\DependencyInjection\Compiler\ParameterLoaderPass;
use Symfony\Component\DependencyInjection\Compiler\PassConfig;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\HttpKernel\Bundle\Bundle;
class ParameterLoaderBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new ParameterLoaderPass(), PassConfig::TYPE_AFTER_REMOVING);
}
}
<?php
namespace Project\DependencyInjection\Compiler;
use App\Entity\SettingCategory;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
class ParameterLoaderPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$em = $container->get('doctrine.orm.default_entity_manager');
$setting = $em->getRepository(SettingCategory::class)->findAll();
$container->setParameter('test', $setting);
}
}
After at all I test the new Parameter in my API controller:
$this->getParameter('Test');
But the following error message appears:
The parameter \"test\" must be defined.
Couple of things going on here. First off, loading config from a database is very unusual in Symfony so it is not surprising that you are having difficulty. Secondly, your process code is never getting called. Part of debugging is making sure that code that you expect to be called is in fact being called. Third, you really got off on a tangent with attempting to add a bundle under config. Way back in Symfony 2 there used to be more bundle related stuff under app/config and it may be that you discovered some old articles and misunderstood them.
But, the big problem here is that Symfony has what is known as a 'compile' phase which basically processes all the configuration and caches it. Hence the CompilerPassInterface. Unfortunately, services themselves are not available during the compile phase. They simply don't exist yet so no entity manager. You need to open your own database connection if you really want to load config from a database. You will want to use just a database connection object and not the entity manager since part of the compile phase is to process the entities themselves.
So get rid of all your code and just adjust your Kernel class:
# src/Kernel.php
class Kernel extends BaseKernel implements CompilerPassInterface
{
use MicroKernelTrait;
public function process(ContainerBuilder $container)
{
$url = $_ENV['DATABASE_URL'];
$conn = DriverManager::getConnection(['url' => $url]);
$settings = $conn->executeQuery('SELECT * FROM settings')->fetchAllAssociative();
$container->setParameter('test',$settings);
}
And be aware that even if you get all this working, you will need to manually rebuild the Symfony cache after updating your settings table. It is not going to be automatic. You really might consider taking a completely different approach.

Silverstripe 4 SapphireTest class can't be found

I've upgraded from SilverStripe 3 to 4 and now my phpUnit tests own't run because they can't find any of my Custom Classes.
There must be something missing from an autoloader or something.
I have a simple test like this
use SilverStripe\Dev\SapphireTest;
class EntityTest extends SapphireTest
{
var $Entity;
function setUp()/* The :void return type declaration that should be here would cause a BC issue */
{
parent::setUp(); // TODO: Change the autogenerated stub
$this->Entity = new \My\API\Client\Model\Entity();
}
function testMethods(){
$this->assertMethodExist($this->Entity,'setName');
}
function assertMethodExist($class, $method) {
$oReflectionClass = new ReflectionClass($class);
assertThat("method exist", true, $oReflectionClass->hasMethod($method));
}
}
and when running I get:
$ php vendor/phpunit/phpunit/phpunit mysite/tests/EntityTest.php
Fatal error: Class 'SilverStripe\Dev\SapphireTest' not found
I ran into a similar issue with SilverStripe 4.1, here is what I found (and resolved).
1) As of 4.1, you need to use --prefer-source instead of --prefer-dist to get the test code. Test code is now omitted from the distributed packages, see https://github.com/silverstripe/silverstripe-framework/issues/7845
2) phpunit must be in require-dev at version ^ 5.7 - I had a different value and this was the cause of the autoload issue.
I've created a test module for reference, see https://github.com/gordonbanderson/travistestmodule
Cheers
Gordon
You're probably missing the test bootstrapping. SS4 still relies on the SilverStripe class manifest to register available classes (not just PSR-4 autoloaders), so you need to include it. Try either of these:
$ vendor/bin/phpunit --bootstrap vendor/silverstripe/framework/tests/bootstrap.php mysite/tests
or create a phpunit.xml file in your root project:
<phpunit bootstrap="vendor/silverstripe/framework/tests/bootstrap.php" colors="true">
</phpunit>
You may also use the equivalent file from the CMS module instead, but you probably won't see any differences until you start to integrate your testsuite into a CI provider.

symfony 2.3 error: autoloader find file but not class

First, sorry if my english it's not so good.
I readed a lot of questions like the one i have, but any solution works.
The question is that I'm developing a porject in Symfony 2.3, yes, i'm beginner using it...
I've created a 'Userbundle', and i want to display the info profile of an user.
When I access to the correct URL I have the famous message error:
"The autoloader expected class "Mylife\UserBundle\Entity\UserRepository" to be defined in file "D:\www\Symfony/src\Mylife\UserBundle\Entity\UserRepository.php". The file was found but the class was not in it, the class name or namespace probably has a typo."
That's my default controller code:
namespace Mylife\UserBundle\Controller;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Mylife\UserBundle\Entity\User;
use Mylife\UserBundle\Form\Frontend\RegisterType;
class DefaultController extends Controller
{
public function profileAction(){
$user_id=1;
$em=$this->getDoctrine()->getEntityManager();
$profile=$em->getRepository('UserBundle:User')
->findProfile($user_id);
return $this->render('UserBundle:Default:profile.html.twig', array( 'profile' => $profile));
}
And my UserRepository.php code:
// src/Mylife/UserBundle/Entity/UserRepository.php
namespace Mylife\UserBundle\Entity;
use Doctrine\ORM\EntityRepository;
class UserRepository extends EntityRepository
{
public function findProfile($user)
{
$em = $this->getEntityManager();
$consult= $em->createQuery('
SELECT u, nk, n
FROM UserBundle:User u
WHERE u.user= :id');
$consult->setParameter('id', $user);
return $consult->getResult();
}
}
I have the same problem when trying to use a form class in the same bundle, but i no see any error in namesapce or class name.
The project structure is:
-src
-Mylife
-UserBundle
....
-Entity
...
-User.php
-UserRepository.php
I'm going mad trying to solve the problem and reading a lot of forums and examples.
I've tryed to dissable APC, to restart Apache, erase the cache, and nothing of this worked.
Thanks a lot!!
Carlos
PD: I'm not sure why appears a piece of code at the top of the error page and why it begins in "getEntityMAnager();..." row... Why is not showing the text code before it?. Image:http://es.tinypic.com?ref=r0s8k5
IMPORTANT: When I generated the entity USer by console, I say "no" when asked to generate repository. May be this is the problem. Any suggestion now?
Thanks again
Try to add this comment in your User entity file:
/**
*
* #ORM\Entity(repositoryClass="YourProject\UserBundle\Entity\UserRepository")
*/
class User
{
...
}
or something like this:
custom repository class in symfony2
Found it!!
It's was a silly mistake. I've began the PHP repository file with
<?
...
and must be
<?php
...
Sorry at all!

Why can't load data these fixtures in Symfony2 project?

I've created a fixtures class inside my bundle's DataFixtures/ORM folder. The actual class looks like this:
use Doctrine\Common\DataFixtures\FixtureInterface,
Company\ShoppingBundle\Entity\Category;
class CategoryFixtures implements FixtureInterface
{
public function load($em)
{
$category1 = new Category()->setName("category1");
$category2 = new Category()->setName("category2");
$em->persist($category1);
$em->persist($category2);
$em->flush();
}
}
I'm not using the AbstractFixture base class, since I don't need references. I've also tried specifying the fixtures path when running the doctrine:fixtures:load console command. I'm following the official docs here.
Nothing wrong with the file naming, or my configuration: I simply forgot to put
<?php
at the top of my file :-D

PHPUnit inclusion path issues

This one's got me stumped. I've been working with PHPUnit for a couple of months now, so I'm not that green...but I look forward to being pointed in the direction of the obvious mistake I'm making! The initialisation process outlined below works fine if I run the "app" from a browser - but PHPUnit is choking...can any one put me out of my misery?
I'm trying to test a homebrew MVC, for study purposes. It follows a typical ZF layout.
Here's the index page:
include './../library/SKL/Application.php';
$SKL_Application = new SKL_Application();
$SKL_Application->initialise('./../application/configs/config.ini');
Here's the application class (early days...)
include 'bootstrap.php';
class SKL_Application {
/**
* initialises the application
*/
public function initialise($file) {
$this->processBootstrap();
//purely to test PHPUnit is working as expected
return true;
}
/**
* iterates over bootstrap class and executes
* all methods prefixed with "_init"
*/
private function processBootstrap() {
$Bootstrap = new Bootstrap();
$bootstrap_methods = get_class_methods($Bootstrap);
foreach ($bootstrap_methods as $method) {
if(substr($method,0,5) == '_init'){
$bootstrap->$method();
}
}
return true;
}
}
Here's the test:
require_once dirname(__FILE__).'/../../../public/bootstrap.php';
require_once dirname(__FILE__).'/../../../library/SKL/Application.php';
class SKL_ApplicationTest extends PHPUnit_Framework_TestCase {
protected $object;
protected function setUp() {
$this->object = new SKL_Application();
}
/**
* Tears down the fixture, for example, closes a network connection.
* This method is called after a test is executed.
*/
protected function tearDown() {
}
public function testInitialise() {
$this->assertType('boolean',$this->object->initialise());
}
}
But I keep stumbling at the first hurdle!!
PHP Warning: include(bootstrap.php): failed to open stream:
No such file or directory in path\to\files\SKL\Application.php on line 9
any ideas?
Use include_once or better yet require_once instead of include to include the bootstrap.php in the Application class file. Despite being already loaded include loads it again but since it's obviously not on the include path you get the error.
Thanks to Raoul Duke for giving me a push in the right direction, here's where I got to so far
1 - add the root of the application to the include path
2 - make all inclusion paths relative to the root of the application
3 - include a file in your unit tests that performs the same function, but compensates for the relative location when it is included. I just used realpath() on the directory location of the files.
The problem I have now is that the darn thing won't see any additional files I'm trying to pass it.
So, I'm trying to test a configuration class, that will parse a variety of filetypes dynamically. The directory structure is like this:
Application_ConfigTest.php
config.ini
The first test:
public function testParseFile() {
$this->assertType('array',$this->object->parseFile('config.ini'));
}
The error:
failed to open stream: No such file or directory
WTF? It's IN the same directory as the test class...
I solved this by providing an absolute (i.e. file structure) path to the configuration file.Can anyone explain to me how PHPUnit resolves it's paths, or is it because the test class itself is included elsewhere, rendering relative paths meaningless?

Resources