我正试图找出如何使用Codeception连接到多个数据库。我甚至尝试直接实例化一个新的PDO实例,但随后codept run
命令过早结束,没有错误消息。
我可以使用Db模块连接到一个数据库,使用$I->seeInDatabase()
等功能,但我试图连接到两个。试图在运行时用$this->getModule('Db')->_reconfigure()
重新配置Db模块也只是停止没有消息的测试。
任何想法?
我可以这样做:
套件配置文件:
actor: API_Tester
lint: true
colors: true
modules:
enabled:
- HelperApi
- Asserts
- REST:
url: http://localhost
depends: PhpBrowser
part: Json
headers:
Accept: application/json
Content-Type: application/json
- Db:
dsn: 'mysql:host=localhost;dbname=DATABASE1'
user: 'DBUSER'
password: 'DBPASSWORD'
dump: 'tests/populate-DATABASE1.sql'
populate: true
cleanup: false
reconnect: true
populator: 'mysql -u $user -p$password -h $host $dbname < $dump'
databases:
DATABASE2_USE_THIS_NAME_IN_YOUR_CODE:
dsn: 'mysql:host=localhost;dbname=DATABASE2'
user: 'DBUSER'
password: 'DBPASSWORD'
dump: 'tests/populate-DATABASE2.sql'
populate: true
cleanup: false
reconnect: true
populator: 'mysql -u $user -p$password -h $host $dbname < $dump'
PHP测试代码:
//Connect to the second database
$I -> amConnectedToDatabase ( 'DATABASE2_USE_THIS_NAME_IN_YOUR_CODE' );
$I -> seeNumRecords ( 1, 'users' );
$I -> seeInDatabase ( 'users', [ 'email' => 'john@example.com' ] );
//Connect back to the default database
$I -> amConnectedToDatabase ( CodeceptionModuleDb::DEFAULT_DATABASE );
$I -> seeNumRecords ( 1, 'sessions' );
$I -> seeInDatabase ( 'sessions', [ 'uniqueness' => $this -> uuid ] );
结果:I am connected to database "DATABASE2_USE_THIS_NAME_IN_YOUR_CODE"
I see num records 1,"users"
I see in database "users",{"email":"john@example.com"}
I am connected to database "default"
I see num records 1,"sessions"
I see in database "sessions",{"uniqueness":"635c798c-05cd-4d9d-b79a-9643...}
我认为这是你想要的:https://github.com/Codeception/Codeception/issues/1634…然而,它还没有实现-也许你可以推动这个问题?
好吧!如果你不使用模拟数据库连接,你可以做这件事,我在symfony中使用codeception时实现过一次。
-
使用
抓取原则服务$doctrine = $I->grabService('Doctrine').
-
现在抓取数据库连接,正如你在doctrine ORM部分提到的。
$connection = $doctrine->getConnection('DB_Name_as_in_ORM')
- 您现在已经连接到所需的数据库,现在您可以使用"doctrine dbal连接方法"对该数据库中的表执行查询。
我想这就是你要找的,也许!
我希望能够使用Doctrine多个管理器设置和所有codeception方法,但它一直在破坏(没有看到设置属性,只在默认管理器等上工作),这就是我想到的:在Helper中,我创建了使用Symfony模块设置条令管理器服务的方法:
class Shared extends CodeceptionModule
{
public DoctrineORMEntityManagerInterface $em;
/**
* @param string $emAlias Name of your entity manager in doctrine.yaml
*/
public function changeEm(string $emAlias): void
{
if ('internal' !== $connection && 'api' !== $emAlias) {
throw new Error('Unknown connection: ' . $emAlias);
}
$doctrine = $this->getService(ManagerRegistry::class);
$em = $doctrine->getManager($emAlias);
// We need to verify that connection is open as it gets shut down on error
if (!$em->isOpen()) {
$doctrine->resetManager($emAlias);
}
$this->setEm($em, $emAlias);
}
public function setEm(EntityManagerInterface $em, string $emAlias): void
{
$this->em = $em; // Just to be safe and have access to selected entity
$this->getModule('Doctrine2')->em = $em;
$sfModule = $this->getModule('Symfony');
/** @var SymfonyBundleFrameworkBundleTestTestContainer $container */
$container = $sfModule->_getContainer();
$service = 'doctrine.orm.' . $emAlias . '_entity_manager';
if ($container->initialized($service)) {
return;
}
$container->set($service, $em);
$sfModule->persistService($service, true);
}
}
,并且总是在所有测试共享的方法的顶部设置默认实体管理器(在我的例子中,是测试父类中的_before):
abstract class BaseCestAbstract
{
public function _before(ApiTester $I): void
{
$I->changeEm('internal'/'api');
[...]
}
}
现在如果你想更改manager Codeception是使用mid-test:
public function testA(ApiTester $I): void
{
$I->changeEm('internal');
[...]
$I->changeEm('api');
[...]
}
所有的方法,如grabEntityFromRepository
应该工作和辅助启动内核API调用应该使用相同的实体。
缺点:
我不知道如何使它与cleanup: true
一起工作,这是一个痛苦,但我主要将其用于REST调用,这些调用无论如何都不能真正与清理一起工作,所以在我的情况下它是可以接受的。
版本:
- Symfony: 6.2.6
- Codeception: 5.0.8
- codeception/module-doctrine2: 3.0.1
- 教义/doctrine-bundle: 2.8.3