Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >问:我如何用茉莉花进行单位测试?

问:我如何用茉莉花进行单位测试?
EN

Stack Overflow用户
提问于 2022-10-25 12:46:15
回答 1查看 21关注 0票数 -1

我有一个Firebase函数,可以检查Chargebee中是否存在电子邮件。它的工作方式如下:

代码语言:javascript
运行
AI代码解释
复制
const cbCmd = chargeBee.customer.list({ email: { is: email }, include_deleted: false, limit: 1 });
const callbackResolver = new Promise<any>((resolve, reject) => {
  void cbCmd.request((err: any, res: WrappedListCustomerResp) => {
     if (err) {
       reject(err);
     }
     resolve(!res.list.find(payee => payee.customer.email === email));
     });
  });
return Promise.resolve(callbackResolver);

基本上,cbCmd包含一个名为request的方法,它最终运行API请求。request被发送给一个函数,它描述了我如何转换Chargebee输出的数据。(Chargebee并没有在他们的打字稿包中完全描述他们在他们的文件中返回的内容。为了更好地描述转换,我研究了返回内容的数据类型,并创建了自己的接口。)

我如何用茉莉花对此进行单元测试?

EN

回答 1

Stack Overflow用户

发布于 2022-10-25 12:46:15

为了充分描述这一解决方案,需要提供一些背景信息。

全局性方法

  1. 模拟所讨论的函数。
  2. 创建/导入测试函数。
  3. 测试。

详细信息

嘲弄有关的功能

与ChargeBee API的交互是通过一个简单的方法完成的:

代码语言:javascript
运行
AI代码解释
复制
import {ChargeBee} from 'chargebee-typescript';
const chargebee = new ChargeBee();

所有的API方法都是这样提供的。在Javascript方面,下面是chargebee.customer发生的情况,例如:

代码语言:javascript
运行
AI代码解释
复制
const resources = require("./resources");
class ChargeBee {
  get customer() {
        return resources.Customer;
    }
}

resources中的每个东西都提供了自己的静态函数,可以完成所需的一切。例如,Customer有以下内容:

代码语言:javascript
运行
AI代码解释
复制
class Customer extends model_1.Model {
    // OPERATIONS
    //-----------
    ...
    static list(params) {
        return new request_wrapper_1.RequestWrapper([params], {
            'methodName': 'list',
            'httpMethod': 'GET',
            'urlPrefix': '/customers',
            'urlSuffix': null,
            'hasIdInUrl': false,
            'isListReq': true,
        }, chargebee_1.ChargeBee._env);
    }
}

RequestWrapper对象包含正在执行实际工作的request方法。这个方法做了一些有趣的事情:

代码语言:javascript
运行
AI代码解释
复制
request(callBack = undefined, envOptions) {
  let deferred = util_1.Util.createDeferred(callBack);
  ...
  return deferred.promise;
}

static createDeferred(callback) {
        let deferred = q_1.defer();
        if (callback) {
            deferred.promise.then(function (res) {
                setTimeout(function () {
                    callback(null, res);
                }, 0);
            }, function (err) {
                setTimeout(function () {
                    callback(err, null);
                }, 0);
            });
        }
        return deferred;
    }

基本上,q_1.defer()创建了一个包含Promise的对象,以及其他的东西。他们使用deferred.promise.then将发送给函数的代码锁存到整个API请求中,以便在Promise开始解析后执行。

要模拟它,您需要重写有关getter的prototype属性。返回customer.list的备用实现。方便地,上面的ChargeBee的createDeferred函数是export编辑的,因此可以利用它来制作一些与ChargeBee的模式非常接近的东西。

整个模拟是这样的:

代码语言:javascript
运行
AI代码解释
复制
spyOnProperty<any>(mockedChargebee.ChargeBee.prototype, 'customer', 'get').and.returnValue({
    list: () => ({
       request: (callBack?: any) => {
           const deferred = Util.createDeferred(callBack);
           deferred.resolve({ list: [] });
           return deferred.promise;
       }
    })
});

重要双边投资条约:

  • 虽然您是在模拟一个函数,但是仍然需要spyOnProperty,因为该函数是作为属性输出的。
  • 您需要监视原型,以便稍后在对象构建过程中使用您模拟的原型。
  • 您需要指定您是在模拟get之三。
  • 我们正在使用Chargebee的Util.createDeferred来确保我们接近于遵循与Chargebee一样的方式。在这里没有保证,但也许这样做比滚动自己承诺的细节更好。
  • 直到稍后解析完整个Promise之后,deferred.resolve才会实际运行。在deferred.resolve({list: []})中,您定义的行为将在稍后解析Promise时发生。如果您非常熟悉resolve的解决顺序,那么可能是显而易见的;这对我来说并不明显。这里的总体行为是:(a)首先通过承诺链发送{list: []};(b)发送{list: []}作为对任何定义为callback的内容的输入;(c)在这个特定示例中,callback将运行resolve(!res.list.find(payee => payee.customer.email === email)),生成resolve(false);(d) false是承诺链的最终结果。

创建/导入测试函数

在完成spyOnProperty之后,我使用了一个简单的动态导入来完成这个操作。这确保初始化代码const chargebee = new ChargeBee();将使用我在spyOnProperty中提供的备用函数。(初始化代码发生在./index中:未显示。)

代码语言:javascript
运行
AI代码解释
复制
const enableSignup = await import('./index').then(m => m.enableSignup);

测试

我碰巧是在使用Firebase,所以我使用了一个Firebase测试库来包装这个函数。然后,使用await进行测试。

代码语言:javascript
运行
AI代码解释
复制
const wrapped = firebaseTestFns.wrap(enableSignup);
const fnd = await wrapped('someemail');
expect(fnd).toBeTrue();
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/74200001

复制
相关文章
React 钩子:useState()
React 是一个流行的JavaScript库,用于构建用户界面。在 React 16.8 版本中引入了钩子(Hooks)的概念,它为函数组件提供了状态管理和其他功能。本文将着重介绍最常用的钩子之一:useState()。
网络技术联盟站
2023/07/13
4160
React 钩子:useState()
React技巧之将useState作为对象
原文链接:https://bobbyhadz.com/blog/react-type-usestate-object[1]
chuckQu
2022/08/19
9820
美丽的公主和它的27个React 自定义 Hook
在上一篇git 原理中我们在「前置知识点」中随口提到了Hook。其中,就有我们比较熟悉的React Hook。
前端柒八九
2023/10/25
8340
美丽的公主和它的27个React 自定义 Hook
react中的useState源码分析
简单说下为什么React选择函数式组件,主要是class组件比较冗余、生命周期函数写法不友好,骚写法多,functional组件更符合React编程思想等等等。更具体的可以拜读dan大神的blog。其中Function components capture the rendered values这句十分精辟的道出函数式组件的优势。
flyzz177
2022/12/14
5150
换个角度思考 React Hooks
从 Vue 迁移到 React ,不太习惯 React Hooks 的使用?也许换个角度思考 Hooks 出现的意义会对你有所帮助。 1 什么是 Hooks 简而言之, Hooks 是个函数,通过使用 Hooks 可以让函数组件功能更加丰富。 在某些场景下,使用 Hooks 是一个比使用类组件更好的主意。 1.1 Hooks 出现的背景 在 Hooks 出现之前,函数组件对比类组件(class)形式有很多局限,例如: 不能使用 state、ref 等属性,只能通过函数传参的方式使用 props 没有生命周
用户1097444
2022/06/29
4.8K0
换个角度思考 React Hooks
React技巧之具有空对象初始值的useState
原文链接:https://bobbyhadz.com/blog/react-typescript-usestate-empty-object[1]
chuckQu
2022/08/19
1.5K0
react的useState源码分析2
简单说下为什么React选择函数式组件,主要是class组件比较冗余、生命周期函数写法不友好,骚写法多,functional组件更符合React编程思想等等等。更具体的可以拜读dan大神的blog。其中Function components capture the rendered values这句十分精辟的道出函数式组件的优势。
flyzz177
2023/01/04
3550
useState的使用
在 React 的函数式组件当中,是没有状态的,但是使用 React 提供的 Hook 可以让函数式组件拥有状态。
小小杰啊
2022/12/21
6190
React技巧之设置input值
原文链接:https://bobbyhadz.com/blog/react-set-input-value-on-button-click[1]
chuckQu
2022/08/19
2K0
React技巧之设置input值
React 中的 useState() 是什么?
在 React 中,useState() 是一个用于在函数组件中声明状态的 Hook。它是 React 16.8 引入的一种新的状态管理方式。
王小婷
2023/09/15
7640
教你如何在 React 中逃离闭包陷阱 ...
众所周知,JavaScript 中的闭包(Closures)一定是这种语言最可怕的特性之一,即使是无所不知的 ChatGPT 也是这样说的。另外它可能也是最隐蔽的语言特性之一,我们在编写 React 代码时经常会用到它,但是大多数时候我们甚至没有意识到这一点。但是,我们终究还是离不开它:如果我们想编写复杂且性能很好的 React 应用,就必须了解闭包。所以,今天我们一起来学习以下几点:
ConardLi
2023/09/11
7700
教你如何在 React 中逃离闭包陷阱 ...
使用React hooks处理复杂表单状态数据
自从React hooks发布以来已经有一段时间了,我很喜欢这个特性。这个hooks把我勾上了!
前端知否
2020/03/23
3.4K0
使用React hooks处理复杂表单状态数据
超性感的React Hooks(三):useState
这几天和许多同学聊了使用React Hooks的感受。总体感觉是,学会使用并不算难,但能用好却并不简单。
用户6901603
2020/07/23
2.4K0
为什么 React Hooks useState 更新不符预期?
不合预期的更新 在定时器中,用useState使数字0做每1秒递增1,但结果不合预期:数字增加一次后便不再改变? Counter.js // Counter.js import React, { us
前端老王
2020/09/14
1.7K0
30分钟精通React今年最劲爆的新特性——React Hooks
你还在为该使用无状态组件(Function)还是有状态组件(Class)而烦恼吗? ——拥有了hooks,你再也不需要写Class了,你的所有组件都将是Function。
桃翁
2018/12/14
2K0
React源码中的useState,useReducer
大家都知道hooks是在函数组件的产物。之前class组件为什么没有出现hooks这种东西呢?
goClient1992
2022/12/07
1K0
React useReducer 终极使用教程
useReducer 是在 react V 16.8 推出的钩子函数,从用法层面来说是可以代替useState。相信前期使用过 React 的前端同学,大都会经历从 class 语法向 hooks 用法的转变,react 的 hooks 编程给我们带来了丝滑的函数式编程体验,同时很多前端著名的文章也讲述了 hooks 带来的前端心智的转变,这里就不再着重强调,本文则是聚焦于 useReducer 这个钩子函数的原理和用法,笔者带领大家再一次深入认识 useReducer。
蒋川@卡拉云
2022/08/31
3.8K0
React useReducer 终极使用教程
React Hooks vs React Component
是不是简单多了!可以看到, Example变成了一个函数,但这个函数却有自己的状态(count),同时它还可以更新自己的状态(setCount)。这个函数之所以这么了不得,就是因为它注入了一个hook– useState,就是这个hook让我们的函数变成了一个有状态的函数。
javascript.shop
2019/09/04
3.4K0
React Hooks vs React Component
使用Immer解决React对象深度更新的痛点
最近接到一个需求,修改一个使用React编写的工单系统,具体就是在创建工单的时候能配置一些增强工单通用性的功能然后把配置传给后端进行存储,乍一听其实挺简单,但是由于数据结构没设计好,写的时候非常的麻烦。
Jou
2023/09/06
1.1K0
使用Immer解决React对象深度更新的痛点
宝啊~来聊聊 9 种 React Hook
文章会为你讲述 React 9种 Hook 的日常用法以及进阶操作,从浅入深彻底掌握 React Hook!
19组清风
2022/02/28
1.1K0
宝啊~来聊聊 9 种 React Hook

相似问题

React useState钩子-更新对象的状态

227

使用useState钩子更新函数后,React不会更新状态

120

使用React中的useState钩子更新对象

10

React钩子useState不更新状态

324

如何使用useState钩子更新对象状态

11
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档