NervJS / taro

开放式跨端跨框架解决方案,支持使用 React/Vue/Nerv 等框架来开发微信/京东/百度/支付宝/字节跳动/ QQ 小程序/H5/React Native 等应用。 https://taro.zone/
https://docs.taro.zone/
Other
35.34k stars 4.77k forks source link

Taro的api 如何写jest单元测试? #9243

Closed kiana-god closed 2 years ago

kiana-god commented 3 years ago

这个特性解决了什么问题?

Taro在做单测时,遇到很多关于api is not function的问题 如: TypeError: _taro2.default.getRealtimeLogManager is not a function useReady, useDidShow, useDidHide 这些都是,如果在useReady 中使用了 useState,还会报错 react重复渲染,让测试覆盖率难以提升。

这个 API 长什么样?

我想请问官方,这些api该如何处理,网上没有如何例子,让单元测试难以执行,希望能help me

b2nil commented 3 years ago

@kiana-god 我在学习写 taro-ui-vue3 的测试时,也是花了很多时间探索。

遇到 api is not function 这种情况,我之前是直接在 jest 配置文件中配置 moduleNameMapper ,将 '^@tarojs/taro$' 指向 "<rootDir>/node_modules/@tarojs/taro/h5.js", 使用 h5 的 api 来测试。

还有另外一种方式是,直接写一个 @tarojs/taro 的 mock 文件,把缺失的 api 从 @tarojs 下的其他依赖文件里面引用,然后挂载到 Taro 上供测试用。例如,useReady, useDidShow, useDidHide 这些就可以直接从 @tarojs/runtime 引用,挂到 Taro 对象里面。其他一些如 createSelectorQuerygetEnv 等,可以直接写一个 mock function 替代,这样需要测试小程序平台的代码时会方便很多。

具体可以参考这里,看看有没有帮助: https://github.com/b2nil/taro-ui-vue3/blob/refactor/monorepo/jest.config.js https://github.com/b2nil/taro-ui-vue3/blob/refactor/monorepo/packages/test-utils/%40tarojs/taro/index.ts

kiana-god commented 3 years ago

@kiana-god 我在学习写 taro-ui-vue3 的测试时,也是花了很多时间探索。

遇到 api is not function 这种情况,我之前是直接在 jest 配置文件中配置 moduleNameMapper ,将 '^@tarojs/taro$' 指向 "<rootDir>/node_modules/@tarojs/taro/h5.js", 使用 h5 的 api 来测试。

还有另外一种方式是,直接写一个 @tarojs/taro 的 mock 文件,把缺失的 api 从 @tarojs 下的其他依赖文件里面引用,然后挂载到 Taro 上供测试用。例如,useReady, useDidShow, useDidHide 这些就可以直接从 @tarojs/runtime 引用,挂到 Taro 对象里面。其他一些如 createSelectorQuerygetEnv 等,可以直接写一个 mock function 替代,这样需要测试小程序平台的代码时会方便很多。

具体可以参考这里,看看有没有帮助: https://github.com/b2nil/taro-ui-vue3/blob/refactor/monorepo/jest.config.js https://github.com/b2nil/taro-ui-vue3/blob/refactor/monorepo/packages/test-utils/%40tarojs/taro/index.ts

感谢你的回答! 我按照demo的配置,去做了以下处理

// jest.config.js moduleNameMapper: { '@tarojs/components': '/packages/test-utils/@tarojs/components/index.ts', '@tarojs/taro': '/packages/test-utils/@tarojs/taro/index.ts', '@tarojs/runtime': '/node_modules/@tarojs/runtime'}

// test-utils/@tarojs/taro/index.ts Taro.useDidShow = runtime.useDidShow;

然而报: TypeError: R.useContext is not a function 😷

使用你说到的第一种方式:将 '^@tarojs/taro$' 指向 "/node_modules/@tarojs/taro/h5.js", 使用 h5 的 api 来测试。

'@tarojs/components': '@tarojs/components/dist-h5/react',

'@tarojs/taro': '/node_modules/@tarojs/taro/h5.js', '@tarojs/runtime': '/node_modules/@tarojs/runtime'

同样曝出:TypeError: R.useContext is not a function

💀💀💀 难受

b2nil commented 3 years ago

Vue 和 React 不太一样。R.useContext 应该是 React 的 API 吧?

jest.config.js 是不是应该配置 reactreact-dom 的 alias, 看看这里:https://github.com/NervJS/taro-ui/blob/next/jest.config.js

PS: 或者看看这里:https://stackoverflow.com/questions/64081681/typeerror-react-usecontext-is-not-a-function-when-mocking-context-providers-w

hongyue-qiu commented 3 years ago

全局mock@tarojs/taro文件,useReady、useRouter等hooks不生效

b2nil commented 3 years ago

@hongyue-qiu

runtime 引入相关的 hooks 函数,然后再挂载到 Taro 上呢?

// @tarojs/taro mock file

const Taro = require('@tarojs/taro/h5')
const runtime = require('@tarojs/runtime')

Taro.useRouter = runtime.useRouter
Taro.useReady = runtime.useRouter

export default Taro
ZakaryCode commented 2 years ago

Jest 参考文档