gpt4 book ai didi

php - 运行PHPUnit测试时如何避免内部调用函数?以及如何为内部性能设置模拟数据?

转载 作者:行者123 更新时间:2023-12-05 02:27:18 25 4
gpt4 key购买 nike

我有一个 Receipt.php 类

<?php
namespace TDD;
class Receipt {
private $user_id = 1;
private $pending_amount;
public function total(array $items = []){
$items[] = $this->pending();
return array_sum($items);
}

public function tax($amount,$tax){
return $amount * $tax;
}

private function pending()
{
$sql = 'select pending_amount from Pending_transtions where user_id =' . $this->user_id . ' limit 1;';
//$pending_amt = $this->mainDb->get_sql_row($sql);
//$this->pending = $pending_amt['pending_amount'];
return $this->pending_amount = 45;
}

public function addTaxPending($tax){
return $this->pending_amount * $tax;
}
}?>

在我的 PHPUnit 文件中,ReceiptTest.php

<?php
namespace TDD\Test;
require(dirname(dirname(__FILE__))).DIRECTORY_SEPARATOR.'vendor'.DIRECTORY_SEPARATOR.'autoload.php';
use PHPUnit\Framework\TestCase;
use TDD\Receipt;


class ReceiptTest extends TestCase{
public function setUp(): void {
$this->Receipt = new Receipt();
}
public function tearDown(): void{
unset($this->Receipt);
}
public function testTotal(){
$input = [0,2,5,8];
$output = $this->Receipt->total($input);
$this->assertEquals(15,$output,"this is not valid");
}

public function testTax(){
$inputAmount = 10.00;
$inputTax = 0.10;
$output = $this->Receipt->tax($inputAmount,$inputTax);
$this->assertEquals(1.0,$output,"this tax expecting 1.0");
}
}?>

问题:

如何忽略内部调用函数 pending() 因为它从数据库中获取数据。同时我想访问$this->pending_amount的属性。

这里的Pending()必须是私有(private)函数。

我怎样才能做到这一点?我正在寻找您有值(value)的解决方案

最佳答案

正确的解决方案是用测试用例中的“模拟”依赖项替换您的依赖项(在您的示例中保存在 $this->mainDb 下的依赖项)。

这是 PHPUnit 手册中的一篇文章,其中展示了如何创建模拟 - https://phpunit.readthedocs.io/en/9.5/test-doubles.html#mock-objects

--

关于注入(inject)方式:您可以通过类构造函数传递 $this->mainDb 实例,或者以公共(public) setMainDb 的形式创建所谓的“接缝”方法(这不是一个优雅的解决方案 - 我宁愿避免它)。

有时我不得不做的另一件事是通过反射替换值:使私有(private)属性可访问并在测试中将其设置为我需要的值。

--

更新:

根据给定的示例,我认为实现预期结果的最简单方法是:

  1. 将测试用例的 setUp 更改为:
  public function setUp(): void
{
$this->Receipt = new Receipt();

$mainDbMock = new class() {
public function get_sql_row() {
return [
"pending_amount" => 0
];
}
};

$this->Receipt->setMainDb($mainDbMock);
}
  1. 将“接缝”方法添加到您的 Receipt 类:
  public function setMainDb($mainDb)
{
$this->mainDb = $mainDb;
}

关于php - 运行PHPUnit测试时如何避免内部调用函数?以及如何为内部性能设置模拟数据?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73324848/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com