I try to run behat tests in a Laravel project.
When I run bin/php vendor/bin/behat:
I have this error:
In GoutteFactory.php line 117:
Method Goutte\Client::setClient() does not exist
My composer.json:
"require": {
"php": "^8.0.2",
[...]
"behat/mink": "^1.9",
"dmore/behat-chrome-extension": "^1.4",
"behat/mink-goutte-driver": "^2.0",
"dmore/chrome-mink-driver": "^2.8"
},
"require-dev": {
"behat/behat": "^3.10",
"friends-of-behat/mink-extension": "^2.6",
[...]
}
}
My behat.yml:
default:
extensions:
Behat\MinkExtension:
goutte: ~
Myfeature is a very simplest tests. It only uses rules provided by Mink, like "Given I am on "/".
My FeatureContext.php
use Behat\Behat\Context\Context;
use Behat\MinkExtension\Context\MinkContext;
/**
* Defines application features from the specific context.
*/
class FeatureContext extends MinkContext implements Context
{
}
Related
I use PHP8, Symfony 5.2 and Doctrine 3.0 in my project,
But the PHP 8 attributes, allowed since Doctrine 2.9, doesn't seem to work.
use Doctrine\ORM\Mapping\Entity;
**
* #Entity(repositoryClass="App\Repository\MyClassRepository")
*/
class MyClass
{
works fine.
use Doctrine\ORM\Mapping\Entity;
#[Entity(repositoryClass: MyClassRepository::class)]
class MyClass
{
Return [critical] Uncaught PHP Exception Doctrine\ORM\Mapping\MappingException: "Class "App\Entity\MyClass" is not a valid entity or mapped super class." at .../vendor/doctrine/orm/lib/Doctrine/ORM/Mapping/MappingException.php line 378
here is my composer.json :
"composer/package-versions-deprecated": "1.11.99.1",
"doctrine/doctrine-bundle": "^2.3",
"doctrine/doctrine-migrations-bundle": "^3.1",
"doctrine/orm": "^3.0",
"symfony/console": "5.2.*",
"symfony/dotenv": "5.2.*",
"symfony/flex": "^1.3.1",
"symfony/framework-bundle": "5.2.*",
"symfony/proxy-manager-bridge": "5.2.*",
"symfony/yaml": "5.2.*"
This is because of doctrine bundle configuration. If all entities within the bundle use attributes just switch the metadata driver from "annotation" to "attribute"
doctrine:
orm:
auto_generate_proxy_classes: true
entity_managers:
default:
...
mappings:
MyBundle:
type: attribute
If some entities within a bundles use attributes and some others annotations - than it is better either choose only one format for metadata or implement a custom metadata driver.
The solution is use a custom AnnotationDriver.
Sample fully works implementation: https://github.com/baraja-core/doctrine/blob/master/src/Orm/Mapping/AnnotationDriver.php
I'm trying to figure out something I couldn't understand while exploring Symfony/Mailer source code.
At first I created a whole new project using these commands:
symfony new my_project_name --version=lts
composer require symfony/mailer
Then, when I was exploring the Symfony\Component\Mailer\Transport\AbstractHttpTransport and saw
it was using Symfony\Contracts\HttpClient\HttpClientInterface.
I was surprised to find out that the HttpClientInterface is not part of my project, I can't find it anywhere and neither does PhpStorm.
How is this possible? Is that a programming trick I am not aware of?
I searched on the internet and find out about Symfony/Contracts project and its purpose but I don't understand how it can be declared in the project and not being part of it.
Here is a part of the source code of the AbstractHttpTransport in Symfony/mailer
use Symfony\Contracts\HttpClient\HttpClientInterface;
...
abstract class AbstractHttpTransport extends AbstractTransport
{
public function __construct(HttpClientInterface $client = null, EventDispatcherInterface $dispatcher = null, LoggerInterface $logger = null)
...
Edit: As required here is the composer.json generated for the project
{
"type": "project",
"license": "proprietary",
"require": {
"php": "^7.1.3",
"ext-ctype": "*",
"ext-iconv": "*",
"symfony/console": "4.4.*",
"symfony/dotenv": "4.4.*",
"symfony/flex": "^1.3.1",
"symfony/framework-bundle": "4.4.*",
"symfony/mailer": "4.4.*",
"symfony/yaml": "4.4.*"
},
"require-dev": {
},
"config": {
"preferred-install": {
"*": "dist"
},
"sort-packages": true
},
"autoload": {
"psr-4": {
"App\\": "src/"
}
},
"autoload-dev": {
"psr-4": {
"App\\Tests\\": "tests/"
}
},
"replace": {
"paragonie/random_compat": "2.*",
"symfony/polyfill-ctype": "*",
"symfony/polyfill-iconv": "*",
"symfony/polyfill-php71": "*",
"symfony/polyfill-php70": "*",
"symfony/polyfill-php56": "*"
},
"scripts": {
"auto-scripts": {
"cache:clear": "symfony-cmd",
"assets:install %PUBLIC_DIR%": "symfony-cmd"
},
"post-install-cmd": [
"#auto-scripts"
],
"post-update-cmd": [
"#auto-scripts"
]
},
"conflict": {
"symfony/symfony": "*"
},
"extra": {
"symfony": {
"allow-contrib": false,
"require": "4.4.*"
}
}
}
The reason why you are unable to find HttpClientInterface, is that you do not require any library that provides a symfony/http-client-implementation.
To allow a transport to use symfony/http-client you will need to explicitly install and configure it.
composer require symfony/http-client
# config/packages/framework.yaml
framework:
# ...
http_client:
max_host_connections: 10
default_options:
headers: { 'X-Powered-By': 'ACME App' }
max_redirects: 7
I don't understand how it can be declared in the project and not being
part of it.
You are able to declare any fully qualified namespace within a PHP application, without the subsequent class or file existing. Example: https://3v4l.org/RIWqS
namespace Foo;
use Non\Existing\NamespaceClass;
class Bar
{
public function __construct()
{
echo NamespaceClass::class;
}
}
new \Foo\Bar(); //Non\Existing\NamespaceClass
Symfony has the capability to ignore autowired arguments that declare a service namespace that does not exist, and will instead supply null for its value.
Clarification
symfony/mailer is a modular component, that does not require the Symfony Framework or the symfony/http-client in order to be used and can be used in virtually any application. Since the mailer can support a variety of different transports and those transports different clients, the code is included to work with them, but they are not a dependency for the mailer package. Allowing you to choose the transports you want to use.
In this instance, extending the AbstractHttpTransport will also require a service that implements the Symfony\Contracts\HttpClient\HttpClientInterface to be provided or overridden. This allows for the HttpClientInterface to be used when it is available.
Symfony Framework specifically looks for the configuration for http_client and will configure the services that can utilize it for you. [sic] Once symfony/http-client is installed and configured, a transport that supports it, will utilize it for the connection.
Source
The HttpClientInterface is supplied in symfony/http-client-contracts. Where a library that provides the implementation, will specify as such in the composer.json as "provide": { "symfony/http-client-implementation": "*" }. Such as symfony/http-client
Which is why no classes within symfony/mailer package extends AbstractHttpTransport, as it is intended to be used by other libraries, such as symfony/amazon-mailer. While symfony/mailer does not provide the implementation for symfony/http-client, multiple classes and methods reference HttpClientInterface, allowing it to be used when available.
For more information see Symfony Contracts and Symfony Http Client
Usage
The various transports that symfony/mailer supports need to be added as desired by you. By default the only transport symfony/mailer comes pre-installed with is SMTP. Where other transports that support the symfony/http-client features but do not require it, are also available.
I'll go straight to the point, I only changed the controller namespace Musique\Controller to STM\Controller
namespace STM\Controller;
use Silex\Application;
class HomeController{
public function indexAction(Application $app){
return $app['twig']->render("index.html.twig");
}
also changed my composer.json file
{
"name": "jasonazoulay/SoTrustMe",
"description": "Tiers de confiance",
"authors": [
{
"name": "Jason Azoulay",
}
],
"require": {
"silex/silex": "^2.0",
"doctrine/dbal": "~2.5",
"twig/twig": "^1.33",
"symfony/asset": "^3.2",
"symfony/twig-bridge": "^3.2",
"symfony/form": "~2.8|3.0.*",
"symfony/translation": "~2.8|3.0.*",
"symfony/config": "~2.8|3.0.*"
},
"autoload": {
"psr-4": {"SoTrustMe\\": "src"}
}
}
and of course the route also
$app->get('/',"STM\Controller\HomeController::indexAction")->bind('home');
and now i get this error
InvalidArgumentException in ControllerResolver.php line 187:
Class "STM\Controller\HomeController" does not exist.
though it was working just fine before I change the namespace !
please help me
Since you are loading your classes with composer and you introduced a new directory in your project you are going to need to re-run: composer dump-autoload
this will regenerate the list of all classes that need to be included in the project and updates the Composer cache. For more detail regarding this issue you could have a look at this question.
I'm new to silex, and I've got a file that creates a few defines. This is its content:
<?php
namespace Config;
define('DS',DIRECTORY_SEPARATOR);
define('ROOT',realpath(__DIR__ . '/../..'));
define('CONFIG',ROOT.DS.'app'.DS.'config');
I'm trying to load it using my composer.json:
{
"require": {
"silex/silex": "~2.0",
"twig/twig": "^1.33",
"doctrine/dbal": "^2.5",
"symfony/twig-bridge": "^3.2",
"boxedcode/silex-knp-menu-service-provider": "^1.0",
"symfony/form": "^3.2",
"symfony/validator": "^3.2",
"symfony/config": "^3.2"
},
"autoload": {
"psr-4": {
"Models\\": "src/MyApp/Models/",
"Config\\": "src/MyApp/Config/"
}
}
}
The defines file is inside src/MyApp/Config/, so I therefore hoped this line would be enough to load the defines file in my index.php file:
use Config\Defines;
But... it seems not... Can anyone tell me how to load the defines file so that I can use my Config class again?
Apparently version 4 of PHPUnit now uses Composer to autoload, which means that the usual means of including PHPUnit in Behat version 2:
require_once 'PHPUnit/Autoload.php';
require_once 'PHPUnit/Framework/Assert/Functions.php';
Doesn't work. I was hoping that /vendor/autoload.php in my Behat folder would include it but it seems like it's not the case.
I guess what I'm asking is what is the general way in which I can include into my code a library that was added by Composer?
You can successfully use default /vendor/autoload.php to both load your libraries and your code. It's hard to say exactly what might be wrong without further details, but make sure your composer dependencies are updated and then simply require the composer's authoload.php. The composer.json should look similar to:
{
"require": {
"behat/behat": "dev-master",
"behat/mink": "dev-master",
"behat/mink-extension": "dev-master",
"behat/mink-browserkit-driver": "dev-master",
"behat/mink-goutte-driver": "dev-master",
"behat/mink-selenium2-driver": "dev-master",
"phpunit/dbunit": "*",
"phpunit/phpunit": "*",
},
"autoload": {
"psr-0": {
"": "./src/"
}
}
}
You can include it in your context hook (this is Behat 3 example though):
/**
* #beforeSuite
*/
public static function setUpSuite()
{
require_once './vendor/autoload.php';
}