我正在使用SQLite连接和原则迁移来进行PHPUnit的功能测试。
我正在使用setUp
方法从头开始进行数据库迁移:
public function setUp()
{
parent::setUp();
@unlink(__DIR__ . '/../../../../../../../var/sqlite.db');
exec('./vendor/bin/doctrine-migrations migrations:migrate --db-configuration=migrations-db-test.php --configuration=migrations_test.yml --no-interaction');
}
然后我就可以从数据库进行写/读了。例如:
public function test_add_event_should_add_event()
{
$service = $this->getAdEventComparativesUpdateService();
$request = AdEventComparativesUpdateServiceRequest::make(self::AD_ID, self::USER_IP);
$response = $service->execute($request);
$this->assertEquals(1, $response->getTotal());
}
,并且有效。即使我使用相同的参数两次调用该服务,它也能正常工作。在这种情况下,只需写一次即可:
public function test_add_two_same_events_should_add_one_event()
{
$service = $this->getAdEventComparativesUpdateService();
$request = AdEventComparativesUpdateServiceRequest::make(self::AD_ID, self::USER_IP);
// Call twice
$service->execute($request);
$response = $service->execute($request);
$this->assertEquals(1, $response->getTotal());
}
当我必须测试必须同时写两个的两个呼叫时,问题就来了:
public function test_add_two_different_events_should_add_two_events()
{
$service = $this->getAdEventComparativesUpdateService();
$request = AdEventComparativesUpdateServiceRequest::make(self::AD_ID, self::USER_IP);
$response = $service->execute($request);
$service = $this->getAdEventComparativesUpdateService();
$request = AdEventComparativesUpdateServiceRequest::make(self::AD_ID, self::OTHER_USER_IP);
$response = $service->execute($request); // **** It fails here
$this->assertEquals(2, $response->getTotal());
}
出现错误:
- XXX :: test_add_two_different_events_should_add_two_event Doctrine \ DBAL \ Exception \ ReadOnlyException:执行带有参数[xxx,“ xxx”,“ xxx”,的'INSERT INTO xxx(xxx,xxx,xxx,xxx)VALUES(?,?,?,?)'时发生异常“ xxx”]:
SQLSTATE [HY000]:常规错误:8次尝试写入只读数据库
xxx / vendor / doctrine / dbal / lib / Doctrine / DBAL / Driver / AbstractSQLiteDriver.php:78 xxx / vendor / doctrine / dbal / lib / Doctrine / DBAL / DBALException.php:128 xxx / vendor / doctrine / dbal / lib / Doctrine / DBAL / Statement.php:178 xxx / vendor / doctrine / orm / lib / Doctrine / ORM / Persisters / Entity / BasicEntityPersister.php:281 xxx / vendor / doctrine / orm / lib / Doctrine / ORM / UnitOfWork.php:1014 xxx / vendor / doctrine / orm / lib / Doctrine / ORM / UnitOfWork.php:378 xxx / vendor / doctrine / orm / lib / Doctrine / ORM / EntityManager.php:356 xxx / vendor / doctrine / orm / lib / Doctrine / ORM / EntityManager.php:235 xxx / DoctrineSession.php:32 xxx / TransactionalApplicationService.php:39 xxx / xxx / test.php:100
我尝试更改两次调用之间的数据库文件权限,但没有任何变化:
public function test_add_two_different_events_should_add_two_event()
{
$service = $this->getAdEventComparativesUpdateService();
$request = AdEventComparativesUpdateServiceRequest::make(self::AD_ID, self::USER_IP);
$response = $service->execute($request);
chmod(__DIR__ . '/../../../../../../../var', 0777);
chmod(__DIR__ . '/../../../../../../../var/sqlite.db', 0777);
chown(__DIR__ . '/../../../../../../../var', 'www-data');
chgrp(__DIR__ . '/../../../../../../../var', 'www-data');
chown(__DIR__ . '/../../../../../../../var/sqlite.db', 'www-data');
chgrp(__DIR__ . '/../../../../../../../var/sqlite.db', 'www-data');
//die;
// Here I checked the /var sqlite.db permissions. They are 0777
$service = $this->getAdEventComparativesUpdateService();
$request = AdEventComparativesUpdateServiceRequest::make(self::AD_ID, self::OTHER_USER_IP);
$response = $service->execute($request);
$this->assertEquals(2, $response->getTotal());
}
关于错误可能从何而来的任何想法?在这种情况下,每个服务呼叫都会呼叫persist
+ flush
。
答案 0 :(得分:0)
很难回答这个问题,因为我们没有真正的[mre]。最常见的是这是一个权限问题,但是您似乎已经探索过此路线。我想我直觉这是怎么回事:
单元测试似乎在每次测试时都会重新创建数据库,即取消链接数据库文件,然后在打开连接时自动创建数据库文件(如果该文件不存在)。因此,在两次写入尝试的情况下,连接首先打开并保持打开状态。然后,数据库文件取消链接被相同或另一个测试调用,随后的写入命令失败。