Php 使用计算字段为连接表创建记录并测试流程

Php 使用计算字段为连接表创建记录并测试流程,php,sql,database,unit-testing,junction-table,Php,Sql,Database,Unit Testing,Junction Table,我在为正在编写的代码编写测试时遇到困难。我尝试为两个表创建一个连接表,如下所示: CREATE TABLE charges ( id bigint PRIMARY KEY, amount float, some_data hstore ) CREATE TABLE shipments ( id bigint PRIMARY KEY, weight float, some_data hstore ) CREATE TABLE distribute

我在为正在编写的代码编写测试时遇到困难。我尝试为两个表创建一个连接表,如下所示:

CREATE TABLE charges (
    id bigint PRIMARY KEY,
    amount float,
    some_data hstore
)

CREATE TABLE shipments (
    id bigint PRIMARY KEY,
    weight float,
    some_data hstore
)

CREATE TABLE distributed_details (
    charges_id bigint references charges (id),
    shipments_id biging references shipments (id),
    amount float,
    another_calculated_field varchar
)
根据
some_data
字段中的一些标准,我必须提取一组费用和一组装运,并通过
shippings.weight
在这些装运中分配每个
费用。金额
。结果将被存储
分布式\u详细信息
。在执行此分发时,我还必须根据
部分\u数据
中的剩余内容执行一些其他计算,这些数据将存储在
分布式\u详细信息中。另一个\u计算字段

class Distributor
{
    public $detailMapper;

    public function distribute($charges, $shipments)
    {
        foreach ($charges as $charge) {
            $distributedAmounts = $this->calculateDistributedAmounts($charge->getAmount(), $shipments);
            foreach ($shipments as $shipment) {
                $distributed_detail = $this->buildDistributedDetail($charge, $shipment, array_shift($distributedAmounts));
                $this->detailMapper->save($distributed_detail);
            }
        }
    }

    public function calculateDistributedAmounts($shipments) {}
    public function buildDistributedDetail($charge, $shipment, $distributedAmount) {}
}

有没有一种好的方法来测试这个函数,并确保这些分发的数量被实际提取并分配给每个记录?出于内存限制的原因,我已将每个细节的持久化委托给此方法中的detailMapper—有时我必须提取数万批货物,并且在一个数组中返回所有由此产生的费用将耗尽我的内存。

如果没有完整的答案,这是不可能的。我的偏好是总是让测试用例安全地在生产环境中运行,这意味着它们不会永久地向数据库提交任何内容。虽然我在Perl中做了大部分工作,但相同的测试方法应该能够在PHP中工作

  • 将数据库连接抽象为一个类,该类为您处理事务

  • 不要在重要的地方使用自动提交,或者如果确实使用了自动提交,请确保它已正确封装

  • 创建一个可以替代实际连接的测试包装器类。这与您的数据库连接具有相同的功能,并且避免了自动提交等。区别在于$database->commit()是一个noop,因此您的应用程序只认为它正在提交对数据库的更改


  • 这允许您为整个逻辑(包括db查询)编写测试用例,而不必冒着用测试数据污染生产环境的风险。

    有点晚了,但我最终为这个问题开发了一个合适的解决方案。这里有两个大问题:

  • 表演。将数万条记录拉入内存不是处理此过程的可行方法
  • 可测试性
  • 该解决方案也由多个部分组成:

  • 不要将所有装运装载到内存中。在我的特定场景中,我使用了一个步骤来逐一查看结果。需要注意的是,它必须再次重新运行查询,但也可能有其他方法来重置指针,而不需要这样做
  • 将构建每个连接记录所需的计算与提取它们所需的过程分开。通过使用类似的实现遍历装运和分发金额,我们也可以单独测试该步骤
  • 最后,将记录分别持久化到您选择的持久化模式(数据映射器、网关等)。使用这最后一部分,您可以包装所有内容,并在需要时对其进行集成测试
  • 我这里没有一个实际的例子,但这是一般的想法