【问题标题】:In memory sqlite always empty despite setup尽管设置,在内存中 sqlite 始终为空
【发布时间】:2017-06-13 01:09:33
【问题描述】:

我关注了站点点Testing Symfony Apps with a Disposable Database 教程。 我在我的测试用例中添加了夹具,并且在设置过程中没有出现错误。如果我在 Fixtures 中添加错误(例如将 nullable=false 字段留空),则会显示错误,因此该代码肯定会被执行。

我的配置:

doctrine:
    dbal:
        default_connection: memory
        connections:
            memory:
                driver: pdo_sqlite
                memory: true
                charset: UTF8

我的 WebTestCase 中的设置:

protected function setUp() {
    parent::setUp();
    self::bootKernel();
    DatabasePrimer::prime(self::$kernel);
    $this->loadFixtures([
        'AppBundle\DataFixtures\ORM\UserData',
        'AppBundle\DataFixtures\ORM\ArtistData'
    ]);
}

然而,在我的 WebTestCase 中,似乎没有表存在。 输出抛出一个 Doctrine Exception 说我的表不存在。

SQLSTATE[HY000]: General error: 1 no such table: my_user_table

如果我在文件中切换到 sql_lite,一切正常,无需任何其他更改:

dbal:
    default_connection: file
    connections:
        file:
            driver:   pdo_sqlite
            path:     %kernel.cache_dir%/test.db
            charset: UTF8

有人在上述教程或使用 sqlite memory db 进行单元测试方面取得了成功,并且有任何提示或想法吗?

更新: 我将我的设置更改为此,以确保内核不会在两者之间关闭。它没有帮助:

parent::setUp();
$this->client = $this->getClient();
MemoryDbPrimer::prime(self::$kernel);
$this->loadFixtures([
    'AppBundle\DataFixtures\ORM\UserData',
    'AppBundle\DataFixtures\ORM\ArtistData'
]);

【问题讨论】:

  • 您是否尝试过将连接名称从memory 更改为default_connection: memory 或其他名称?可能是使用该保留字(因为它是连接数据本身的属性)会导致问题。也可能值得发布您的夹具文件。
  • @JohnJoseph:我试过了,但没有任何区别。我的固定装置文件很大,所以我不想那样做。另外,由于它更多地在 sqllte 文件中工作,我怀疑我的固定装置是问题所在。
  • 我仍然认为你的内核会以某种方式在两者之间关闭/重新启动。要找出位置,您可以在vendor/symfony/symfony/src/Symfony/Bundle/FrameworkBundle/Test/KernelTestCase.php 中的bootKernel() 函数顶部添加print("bootKernel() called\n"); debug_print_backtrace();,然后运行受影响的测试用例之一。
  • 您找到解决问题的方法了吗?我也有类似的问题。

标签: sqlite symfony doctrine phpunit functional-testing


【解决方案1】:

当你

$client->request(<METHOD>, <URL>);

调用

Symfony\Bundle\FrameworkBundleClient::doRequest($request)

在请求后内核默认关闭,您的内存数据库被丢弃。

如果你打电话

client->disableReboot(); 

在您的测试的 setup() 函数中,此行为被禁用,您可以运行整个套件。

【讨论】:

  • $this->client->disableReboot();这对我来说是缺失的部分 - 防止了我得到的 TableNotFoundException。
  • 客户端->disableReboot(); ... manno ...为此挖了4个小时。谢谢!
【解决方案2】:

我假设您在测试函数中调用 createClient()createClient() 做的第一件事就是调用static::bootKernel()。这基本上意味着您在 setUp() 中启动的内核将被关闭并启动一个新内核,并使用内存 SQLite 数据库的新实例。

您可以将createClient() 调用移动到您的setUp() 中,替换bootKernel(),以避免这种情况:

class MyTest extends WebTestCase
{
    private $client = null;

    public function setUp()
    {
        $this->client = static::createClient();
        // prime database
    }

    public function testSomething()
    {
        $crawler = $this->client->request('GET', '/');
        // ...
    }
}

【讨论】:

  • 好点,但是,这已经在我的测试中完成了:protected function setUp() { parent::setUp(); $this-&gt;client = $this-&gt;makeClient(); ...
  • 也许您应该向我们展示您的一项测试功能。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多