Reputation: 4253
I have such configuration file:
src/AppBundle/services.yml
#imports:
# - { resource: '../../app/config/config.yml' }
parameters:
#laikinas, tikras yra config.yml
app_url: http://app.guru
services:
UserManagement:
class: Tests\AppBundle\SharedCode\UserManagement\UserManagement
arguments: [%app_url%]
UserRegistrationContext:
class: Tests\AppBundle\features\user_registration\bootstrap\UserRegistrationContext
arguments: ['@UserManagement']
tests/AppBundle/features/user_registration/bootstrap/UserRegistrationContext.php
<?php
namespace Tests\AppBundle\features\user_registration\bootstrap;
use Behat\Behat\Tester\Exception\PendingException;
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
use Tests\AppBundle\SharedCode\UserManagement\UserManagement;
use AppBundle\Controller\UserController;
use Tests\AppBundle\features\BaseContext;
/**
* Defines application features from the specific context.
*
* To run:
* sudo vendor/behat/behat/bin/behat
* tests/AppBundle/features/user_registration/user_registration.feature
* --stop-on-failure
*/
class UserRegistrationContext extends BaseContext implements Context, SnippetAcceptingContext
{
private $userManagement;
/**
* UserRegistrationContext constructor.
*/
public function __construct(UserManagement $userManagement)
{
//$this->userManagement = new UserManagement();
$this->userManagement = $userManagement;
parent::__construct();
}
}
I run behat tests and get an error:
vagrant@php7dev:/shared$ sudo vendor/behat/behat/bin/behat tests/AppBundle/features/user_registration/user_registration.feature
Fatal error: Uncaught Symfony\Component\Debug\Exception\FatalThrowableError: Type error: Argument 1 passed to Tests\AppBundle\features\user_registration\bootstrap\UserRegistrationContext::__construct() must be an instance of Tests\AppBundle\SharedCode\UserManagement\UserManagement, none given in /shared/tests/AppBundle/features/user_registration/bootstrap/UserRegistrationContext.php:30
Stack trace:
#0 [internal function]: Tests\AppBundle\features\user_registration\bootstrap\UserRegistrationContext->__construct()
#1 /shared/vendor/behat/behat/src/Behat/Behat/Context/ContextFactory.php(123): ReflectionClass->newInstance()
#2 /shared/vendor/behat/behat/src/Behat/Behat/Context/ContextFactory.php(80): Behat\Behat\Context\ContextFactory->createInstance(Object(ReflectionClass), Array)
#3 /shared/vendor/behat/behat/src/Behat/Behat/Context/Environment/Handler/ContextEnvironmentHandler.php(104): Behat\Behat\Context\ContextFactory->createContext('Tests\\AppBundle...', Array)
#4 /shared/vendor/behat/behat/src/Behat/Testwork/Environme in /shared/tests/AppBundle/features/user_registration/bootstrap/UserRegistrationContext.php on line 30
We can see that in services.yml I have given the parameter. What is wrong?
For services.yml to be read, as I understand I need exctension class, here it is:
src/AppBundle/DependencyInjection/AppExtension.php
<?php
namespace AppBundle\DependencyInjection;
use Symfony\Component\DependencyInjection\Loader\YamlFileLoader;
use Symfony\Component\HttpKernel\DependencyInjection\Extension;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\Config\FileLocator;
class AppExtension extends Extension
{
/**
* @param array $configs configs
* @param ContainerBuilder $container container
* @return null
*/
public function load(array $configs, ContainerBuilder $container)
{
// ... you'll load the files here later
$loader = new YamlFileLoader(
$container,
new FileLocator(__DIR__ . '/../')
);
$loader->load('services.yml');
}
}
Upvotes: 0
Views: 1373
Reputation: 4253
Thank you so much Matteo, so awesome, from his comment alone was able to fix the problem.
It turns out that I had to use Symfony2 Extension and configure dependencies in behat.yml instead of my config. Here is how behat.yml looks now:
default:
autoload:
'': %paths.base%/tests/AppBundle/features/user_registration/bootstrap
formatters:
progress: ~
suites:
app_features:
paths: [ %paths.base%//tests/AppBundle/features ]
contexts:
- Tests\AppBundle\features\user_registration\bootstrap\UserRegistrationContext:
userManagement: '@UserManagement'
- Tests\AppBundle\features\user_login\bootstrap\UserLoginContext:
userManagement: '@UserManagement'
- Tests\AppBundle\features\password_reset\bootstrap\PasswordResetContext:
userManagement: '@UserManagement'
extensions:
Behat\Symfony2Extension: ~
And I even commented out UserManagement from src/AppBundle/services.yml and it finds it somehow, I do not understand how actually.
And here is something written about this, I googled again for symfony3 behat dependency injection after I solved the problem: http://docs.behat.org/en/v3.0/cookbooks/1.symfony2_integration.html
I remember I saw this page before, but this was not in my head when solving this problem. Maybe because in the example there was Session being injected which is symfony component, while UserManagement class was my created component.
Update:
Done from scratch and will give minimal versions of files how they look:
behat.yml has to be in the root of the project. http://docs.behat.org/en/v3.0/cookbooks/1.symfony2_integration.html
default:
suites:
default:
contexts:
- FeatureContext:
userRepository: "@user_repository"
extensions:
Behat\Symfony2Extension: ~
features/bootstrap/FeatureContext.php
use AppBundle\Repository\UserRepository;
use Behat\Behat\Tester\Exception\PendingException;
use Behat\Behat\Context\Context;
use Behat\Behat\Context\SnippetAcceptingContext;
use Behat\Gherkin\Node\PyStringNode;
use Behat\Gherkin\Node\TableNode;
/**
* Defines application features from the specific context.
*/
class FeatureContext implements Context, SnippetAcceptingContext
{
private $userRepository;
/**
* Initializes context.
*
* Every scenario gets its own context instance.
* You can also pass arbitrary arguments to the
* context constructor through behat.yml.
*/
public function __construct(UserRepository $userRepository)
{
$this->userRepository = $userRepository;
}
//other methods
}
Pay attention that there has to be matches of keys - if there is such key:
userRepository: "@user_repository"
then in constructor the variable has to be named
$userRepository
Upvotes: 0