Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Php 如何在单元测试中捕获无效的查询错误_Php_Mysql_Database_Unit Testing_Mocking - Fatal编程技术网

Php 如何在单元测试中捕获无效的查询错误

Php 如何在单元测试中捕获无效的查询错误,php,mysql,database,unit-testing,mocking,Php,Mysql,Database,Unit Testing,Mocking,几个月前,我在开发过程中引入了单元测试 我刚刚遇到了这个问题:我为一个简单的函数编写了一个测试用例,并且依赖于一个数据库查询。我使用了模拟对象而不是数据库适配器对象。测试通过了,到目前为止还不错 但这是一个假阳性。模拟对象从数据库返回了预期的结果集(它必须返回,因为它是一个模拟对象),但由于键入错误,实际查询没有返回有效的结果集 解决此问题的一种方法是,如果查询未生成记录集,则抛出异常 $db->query($query); $resultset = $db->fetchAll();

几个月前,我在开发过程中引入了单元测试

我刚刚遇到了这个问题:我为一个简单的函数编写了一个测试用例,并且依赖于一个数据库查询。我使用了模拟对象而不是数据库适配器对象。测试通过了,到目前为止还不错

但这是一个假阳性。模拟对象从数据库返回了预期的结果集(它必须返回,因为它是一个模拟对象),但由于键入错误,实际查询没有返回有效的结果集

解决此问题的一种方法是,如果查询未生成记录集,则抛出异常

$db->query($query);
$resultset = $db->fetchAll();
if(!is_array($resultset)) throw new UnexpectedValueException("Query does not yield a result set");
这种方法只会使整个脚本失败(如果没有捕获异常),测试肯定会失败


我的问题是:这是正确的方法,还是你会推荐其他方法?我认为你的方法是错误的。为什么?

  • 您无法测试模型是否正确使用数据库(例如,插入、更新或删除记录,选择记录)

  • 您无法检查查询是否正常

  • 我们如何做到这一点

    我们使用migrationsystem(),它允许我们轻松地更改数据库。我们的系统有两个数据库——用于生产和测试

    当我们创建一个新的更改(例如,使用一些alter列)时,我们运行迁移,将更改应用到这些数据库

    在测试中,我们使用在每次测试后回滚的事务。您可以看看这个-(这是我们的框架),因为您可以看到有覆盖方法
    setUp
    tearDown
    ,它们在每次测试后启动并回滚事务。您应该编写一个集成测试

    这是怎么回事

    你可以找混凝土

    工作流程:

  • 运行正在启动事务的方法
    setUp
  • 创建对象
    Product
    并插入数据库
  • 获取具体对象
  • 断言
  • 运行方法
    tearDown
    ,将数据库回滚到以前的状态

  • 这是。

    谢谢,这确实很有帮助。到目前为止,我阅读的所有单元测试介绍都建议模拟数据库适配器。你的方法更有意义。
    public function shouldPersistModel()
    {
        //given
        $product = new Product();
        $product->name = 'Sport';
    
        //when
        $id = $product->insert();
    
        //then
        $this->assertNotNull($id);
        $actual = Product::findById($id);
        $this->assertEquals('Sport', $actual->name);
    }