duanshan188866 2013-08-08 06:35
浏览 80
已采纳

PHPUnit测试数据库与Zend_Test_PHPUnit_DatabaseTestCase和数据库适配器问题

I have implemented the abstract class from Database testing with Zend Framework and PHPUnit which implements Zend_Test_PHPUnit_DatabaseTestCase, however I am having issues with the way my database abstraction layer uses the Zend_Db_Adapter and how the unit test uses its own database connection, createZendDbConnection

The code in question is:

public function testSaveInsert()
{
    $hostModel = new MyLibrary_Model_Host();
    $hostModel->setName('PHPUnit - Host Test 1')
        ->setDescription('Host Test Description 1');

    $databaseAPI = new MyLibrary_DatabaseAPI();
    $databaseAPI->addHost($hostModel);

    $hosts = $databaseAPI->getHosts();
    Zend_Debug::dump($hosts);

    // get data from the testing database
    $dataSet = new Zend_Test_PHPUnit_Db_DataSet_QueryDataSet($this->getConnection());
    $dataSet->addTable('HOST', "SELECT host.NAME
            , host.DESCRIPTION
        FROM HOST_TABLE host WHERE name like 'PHPUnit -%'");

    // verify expected vs actual
    $this->assertDataSetsMatchXML('hostInsertIntoAssertion.xml', $dataSet);
}

The MyLibrary_DatabaseAPI() class has a constructor

$hostDb = Zend_Registry::get('config')->dbConnectionIds->hostDb;
$this->appDb = Zend_Registry::get($hostDb);

The addHost method takes the host model attributes and converts them to parameters to be passed into the package function, using the database connection set in the registry. I have a flag in the method call to commit (business requirements determine this), so I can chose when to do this.

At the time of Zend_Debug::dumping the results the host has been added to the database table, however when I run the assertDataSetsMatchXML test it is not picking up a host was added and is failing.

I suspect is the issue is when I instantiate Zend_Test_PHPUnit...($this->getConnection) it uses createZendDbConnection which creates a new database session which isn't aware of the previous one and because I haven't 'committed' the addHost it isn't aware of it?

If I run the method call and commit the record it is added to the host table and the test passes, but I cannot rollback the results using the createZendDbConnection so the record remains in the table, which i dont want. Essentially I want a silent test, come in, test and leave no footprint.

Any ideas on how I can resolve this issue? The basis behind testing this way is the database has an api to tables so i don't directly CRUD in the database. The PHP database API class reflects the calls I can make to the database API so I want to test each of these methods.

  • 写回答

1条回答 默认 最新

  • douyan1944 2013-08-08 07:10
    关注

    You should allow your classes to inject the dependencies they have instead of fetching them from the registry. This is a pattern called "dependency injection" and comes in about two different types: Inject via constructor pattern, or via a setter.

    That way, your DatabaseAPI would accept a database connection when instantiated, instead of fetching one from "somewhere", and that database connection can be a mock object instead of the real thing.

    The mock can be configured to wait for certain method calls, can check if the parameters are correct, and might even return a defined result. All those mock calls are part of the test.

    The biggest benefit: Mocks are only taking place in memory, they do not affect any permanent storage like a database. That means they are way faster than the real database access, and they leave no trace behind after their variable is unset or forgotten.

    The only places where software really needs to use the underlying hardware is in those classes that must do the actual work. Fortunately for you, you are using the classes of the Zend framework, and you can consider them tested need not do it yourself again (unless you suspect an error).

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 什么设备可以研究OFDM的60GHz毫米波信道模型
  • ¥15 不知道是该怎么引用多个函数片段
  • ¥15 爬取1-112页所有帖子的标题但是12页后要登录后才能 我使用selenium模拟登录 账号密码输入后 会报错 不知道怎么弄了
  • ¥30 关于用python写支付宝扫码付异步通知收不到的问题
  • ¥50 vue组件中无法正确接收并处理axios请求
  • ¥15 隐藏系统界面pdf的打印、下载按钮
  • ¥15 基于pso参数优化的LightGBM分类模型
  • ¥15 安装Paddleocr时报错无法解决
  • ¥15 python中transformers可以正常下载,但是没有办法使用pipeline
  • ¥50 分布式追踪trace异常问题