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

2024-05-17

我有一个类 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.

Here Pending()必须是私有函数。

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


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

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

--

说到注射方式:你可以通过$this->mainDb通过类构造函数实例化,或者以 public 形式创建所谓的“seam”setMainDb方法(这不是一个优雅的解决方案 - 我宁愿避免它)。

有时我必须做的另一件事是通过反射替换值:使私有属性可访问并将其在测试内部设置为我需要的值。

--

Update:

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

  1. 更改测试用例setUp to:
  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 class:
  public function setMainDb($mainDb)
  {
    $this->mainDb = $mainDb;
  }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

运行PHPUnit测试时如何避免内部调用函数?以及如何设置内部性能的模拟数据? 的相关文章

随机推荐

  • SQLite (Android):使用 ORDER BY 更新查询

    Android SQLite 我想要在 myTable 中的其他行之间插入行在android中使用SQLite 为此 我尝试增加从第 3 行开始的所有行的 id 这样 我就可以在位置 3 处插入新行 myTable 的主键是列 id 表中没
  • 如何制作 github PR 请求审查整个文件?

    有这个问题 https github com isaacs github issues 284这是相关的 允许对更改集之外的部分代码进行注释 我只是想知道是否有人有聪明的解决方法或流程来实现类似的 也许更简单的事情 因此 我有一组不同的文件
  • 如何更改 FacetGrid 中的边距标题颜色

    使用 Seaborn Facet Grids 如何仅更改边距标题的颜色 注意g set titles color red 更改两个标题 p sns load dataset penguins sns displot data p x fli
  • 将消息从 AWS Lambda 发布到 AWS IoT

    我正在尝试使用 Nodejs 将消息从 AWS Lamba 发布到 AWS IoT 我已压缩该项目并上传到 AWS IoT 下面是代码片段 var awsIot require aws iot device sdk var device a
  • 如何在 Linux 中编写文本模式 GUI? [关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 当我编写脚本 程序时 我经常想弹出一个简单的文本 gui 来提示输入 我该怎么做 例如 来自 Shel
  • 如何在 C++ 项目的 Cmake 文件上添加 Mac OS 框架

    我正在尝试将外部库 Vulkan 添加到我的项目中 这个库是预编译的并且有一个框架 我的项目树 build source Entry main cpp include ext vulkan macos include lib Framewo
  • 阻止 TensorFlow 访问 GPU? [复制]

    这个问题在这里已经有答案了 有没有一种方法可以纯粹在CPU上运行TensorFlow 我机器上的所有内存都被运行 TensorFlow 的单独进程占用 我尝试将 per process memory fraction 设置为 0 但未成功
  • 从 Django 调用 Postgres SQL 存储过程

    我正在开发一个带有 Postgresql 数据库的 Django 项目 我编写了一个可以在 Postgres 上完美运行的存储过程 现在我想从 Django 1 5 调用该存储过程 我已经编写了代码 但它提示错误 CREATE FUNCTI
  • 如何覆盖 Django 的默认管理模板和布局

    我正在尝试覆盖 Django 的默认模板 现在只有base site html 我正在尝试更改 django 管理文本 我做了以下事情 我在我的应用程序目录中创建了一个文件夹 opt mydjangoapp templates admin
  • Android Lollipop prepareAsync() 需要很长时间才能返回

    在 Samsung Galaxy Note 4 上的 Android Lollipop 几周前刚刚从 4 4 4 更新 上 prepareAsync 几乎需要 20 秒来加载实时流 在 4 4 4 上 只需要 2 3 秒 并且没有错误 见下
  • 配置根项目“firebase_auth”时出现问题

    my error 我无法构建 apk 发布文件 我完成了应用程序一段时间 没有出现错误 几天后 我在构建应用程序时收到此错误 请告诉我如何摆脱它 我尝试了 4 个小时 什么也没得到 FAILURE Build failed with an
  • 跨域XMLHttp请求

    这是我的情况 我有一台 Web 服务器机器 一台客户端机器和第三台运行一些侦听 XMLHttpRequest 的程序的机器 客户端从客户端计算机访问网络服务器 进行一些更改 然后单击 保存 此时 数据被发送回网络服务器和第三台机器 所有这些
  • 如何将异常序列化为Json

    C 异常是 ISerialisable 因此它们不能也是 DataContract 因此我无法使用 JsonDataContractSerializer 将异常序列化为 JSON 的替代方案是什么 由于这个问题还没有真正得到解答 只需创建一
  • 按钮未显示在屏幕上

    我创建了一个应用程序 其中显示带有图像和文本的列表视图 我在页面末尾添加按钮 但这没有显示在屏幕上 我是 Android 新手 我该如何解决这个问题 这是我的 UI XML 代码
  • 如何禁用 GNOME 桌面屏幕锁定? [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 如何阻止 GNOME 桌面在几分钟空闲时间后锁定屏幕 我已经尝试过官方手册了在红帽 https access redhat com doc
  • 如何将画廊意图中的“打开”更改为“完成”?

    我使用以下意图打开画廊来选择多个图像和视频 Intent intent new Intent intent setType image video intent putExtra Intent EXTRA ALLOW MULTIPLE tr
  • 我什么时候应该使用 -inl.h 文件?

    我刚刚注意到这个项目 http google styleguide googlecode com svn trunk cppguide xml showone The inl h Files The inl h Files in the G
  • 如何防止 CFDocument 中的内容中间发生分页?

    我使用 cfdocument 标签从 html css 动态生成 PDF 文件 有些内容块我不想跨越多个页面 经过一番搜索后 我发现根据文档支持 page break inside 样式 然而 在我的测试中 声明 page break in
  • R 编程常用工具

    如果已经以不同的方式问过这个问题 我深表歉意 但我找不到任何达到我想要的东西 我真的是从其他软件包 SPSS 开始接触 R 的 当我了解真正可以做什么时 我意识到我还需要其他 工具 这让我想到了我的问题 您有哪些用于开发 R 代码的设置 我
  • 运行PHPUnit测试时如何避免内部调用函数?以及如何设置内部性能的模拟数据?

    我有一个类 Receipt php