惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

G
GRAHAM CLULEY
V
V2EX
WordPress大学
WordPress大学
博客园 - Franky
Last Week in AI
Last Week in AI
博客园 - 司徒正美
有赞技术团队
有赞技术团队
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
博客园 - 【当耐特】
V
Visual Studio Blog
C
CERT Recently Published Vulnerability Notes
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Jina AI
Jina AI
Attack and Defense Labs
Attack and Defense Labs
腾讯CDC
The Hacker News
The Hacker News
Hugging Face - Blog
Hugging Face - Blog
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
J
Java Code Geeks
人人都是产品经理
人人都是产品经理
阮一峰的网络日志
阮一峰的网络日志
T
Tailwind CSS Blog
S
SegmentFault 最新的问题
大猫的无限游戏
大猫的无限游戏
小众软件
小众软件
A
Arctic Wolf
量子位
博客园 - 聂微东
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
N
News and Events Feed by Topic
雷峰网
雷峰网
博客园_首页
Google Online Security Blog
Google Online Security Blog
Spread Privacy
Spread Privacy
罗磊的独立博客
H
Hacker News: Front Page
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
月光博客
月光博客
TaoSecurity Blog
TaoSecurity Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
博客园 - 三生石上(FineUI控件)
宝玉的分享
宝玉的分享
IT之家
IT之家
The Cloudflare Blog
爱范儿
爱范儿
博客园 - 叶小钗
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Apple Machine Learning Research
Apple Machine Learning Research
酷 壳 – CoolShell
酷 壳 – CoolShell

博客园 - 稻草人.Net

Python多环境管理神器pyenv+poetry python包管理利器poetry和conda使用简介 Spring REST 接口自定义404不能捕获NoHandlerFoundException问题 MacOS 安装Podman 替代Docker Prettier + ESLint + TS常用配置项 React Native V0.64.4版本 开发环境搭建及问题 Nodejs环境Eggjs加签验签示例 Mac安装compass失败相关问题 MySQL手动安装方法 Docker+Jenkins更换国内插件源 Chrome91版本 SameSite cookies 被移除后的解决方法 推荐几个文档中心搭建工具 前端开发Docker快速入门(二)制作镜像并创建容器 微信开放平台-第三方平台代小程序实现业务 微信开放平台-第三方平台授权流程及接口概述 Vuejs 3 Release:One Piece. Vuejs 3.0 正式版发布!代号:海贼王 尝试使用Nestjs搭建GraphQL服务 Mac安装Arduino搭建ESP8266 NodeMCU开发环境 vscode配置typescript和eslint的环境
用vscode进行jest单元测试并调试代码
稻草人.Net · 2020-05-01 · via 博客园 - 稻草人.Net

首先需要安装相应的包:npm i -D jest ts-jest supertest jest-express jest-sonar-reporter sonarqube-scanner

1、单元测试:npm run test

2、代码覆盖率:npm run test:cov

3、使用SonarQube平台分析:npm run sonar,完成后就可以使用SonarQube web查看相关数据

4、如何调试单元测试的代码,有二种方法:1、在vscode终端运行npm run test:debug,2、在vscode的launch.json中添加相应的代码,然后就右直接选择运行中的Debug Jest Tests来启动

在pageage.json增加如下配置

 1 "scripts": {
 2     "lint": "eslint 'src/**/*.{ts,js}'",
 3     "lint:fix": "eslint 'src/**/*.{ts,js}' --fix",
 4     "lint:ts": "tslint -p tsconfig.json -c tslint.json",
 5     "test": "jest --runInBand --forceExit --colors",
 6     "test:watch": "jest --watch",
 7     "test:cov": "jest --coverage",
 8     "test:debug": "node --inspect-brk -r tsconfig-paths/register -r ts-node/register node_modules/.bin/jest --runInBand",
 9     "test:e2e": "jest --runInBand --config ./test/jest-e2e.json",
10     "sonar": "node sonar-project.js"
11   },
12 "engines": {
13     "node": ">=8.9.0"
14   },
15   "jest": {
16     "moduleFileExtensions": [
17       "js",
18       "json",
19       "ts"
20     ],
21     "moduleNameMapper": {
22       "^@creative(.*)$": "<rootDir>/modules/creative$1",
23       "^@admin(.*)$": "<rootDir>/modules/admin$1",
24       "^@configuration(.*)$": "<rootDir>/modules/configuration$1",
25       "^@common(.*)$": "<rootDir>/common$1",
26       "^@auth(.*)$": "<rootDir>/modules/auth$1"
27     },
28     "rootDir": "src",
29     "testRegex": ".spec.ts$",
30     "transform": {
31       "^.+\\.(t|j)s$": "ts-jest"
32     },
33     "collectCoverageFrom": [
34       "**/*.(t|j)s"
35     ],
36     "testResultsProcessor": "jest-sonar-reporter",
37     "coverageDirectory": "../coverage",
38     "coveragePathIgnorePatterns": [
39       "/node_modules/"
40     ],
41     "testEnvironment": "node"
42   },
43   "jestSonar": {
44     "reportPath": "coverage",
45     "reportFile": "test-reporter.xml",
46     "indent": 4
47   }

sonar-project.js

const sonarqubeScanner = require('sonarqube-scanner');
const parameters = {
    serverUrl:  'http://localhost:9000',
    token: 'XXX',
    options : {
        'sonar.projectVersion': '1.1',
        'sonar.projectName': 'create-server',
        'sonar.projectKey': 'create-server',
        'sonar.sourceEncoding': 'UTF-8',
        'sonar.scm.provider': 'git',
        'sonar.language': 'typescript',
        'sonar.sources': 'src',
        'sonar.inclusions': 'src/**',
        'sonar.exclusions': '**/node_modules/**,**/coverage/**',
        'sonar.tests': 'test',
        'sonar.ts.tslint.configPath': 'tslint.json',
        'sonar.test.inclusions': 'src/**/*.spec.ts,test/**/*.e2e-spec.ts',
        'sonar.testExecutionReportPaths':  'coverage/test-reporter.xml',
        'sonar.javascript.lcov.reportPaths': 'coverage/lcov.info',
    }
}
sonarqubeScanner(parameters, () => process.exit());

示例代码  

 1 import { Test, TestingModule } from '@nestjs/testing';
 2 import { AppController } from './app.controller';
 3 import { AppService } from './app.service';
 4 import { ApplicationModule } from './app.module';
 5 import { Request } from 'jest-express/lib/request';
 6 import { Response } from 'jest-express/lib/response';
 7 
 8 describe('AppController', () => {
 9     let appController: AppController, appService: AppService, req: Request, res: Response;
10 
11     beforeAll(async () => {
12         const module: TestingModule = await Test.createTestingModule({
13             imports: [ApplicationModule],
14         }).compile();
15 
16         appController = module.get<AppController>(AppController);
17         appService = module.get<AppService>(AppService);
18         req = new Request();
19         res = new Response();
20     });
21 
22     describe('controller test', () => {
23         it('Mock一个函数返回动态测试数据', () => {
24             expect.assertions(1);
25 
26             // 通过jest.fn()来Mock一个回调函数返回测试数据
27             const mockfn = jest.fn();
28             const result = mockfn.mockReturnValue(`[${new Date()}]: Welcome to use youtu test service.`);
29 
30             // 调用Controller的root方法,root方法调用service里的root方法返回相应的结果与mock结果是否达到预期
31             expect(appController.root()).toBe(result());
32         });
33 
34         it('监听函数是否被正常调用', async (done) => {
35             // 验证第二个断言被调用,测试异步代码时这通常很有用
36             expect.assertions(3);
37             const spyfn = jest.spyOn(appService, 'getAllUsers');
38             req.setBody({ name: 'mock data' });
39             expect(await appController.getAllUsers(req, res)).toBe('test service');
40             // 用来判断一个函数是否被调用过
41             expect(spyfn).toHaveBeenCalled();
42 
43             // 判断函数被调用过几次
44             expect(spyfn).toHaveBeenCalledTimes(1);
45             done();
46         });
47 
48         it('Mock函数调用', async (done) => {
49             // 验证第二个断言被调用,测试异步代码时这通常很有用
50             expect.assertions(3);
51             const resultMock = Promise.resolve('test mock');
52 
53             // 监听并Mock掉appService.getAllUsers函数的返回结果,当这个函数有依赖第三方的时候可以使用
54             const spyfn = jest.spyOn(appService, 'getAllUsers').mockImplementation(() => resultMock);
55             expect(await appController.getAllUsers(req, res)).toBe('test mock');
56 
57             // 用来判断一个函数是否被调用过
58             expect(spyfn).toHaveBeenCalled();
59 
60             // 判断函数被调用过几次
61             expect(spyfn).toHaveBeenCalledTimes(2);
62             done();
63         });
64 
65         it('promise throws', async (done) => {
66             expect.assertions(1);
67             const message = 'test service error';
68             const result2 = Promise.reject(new Error(message));
69 
70             // 劫持getAllUsers函数并返回一个异常给appController
71             jest.spyOn(appService, 'getAllUsers').mockImplementation(() => result2);
72             await expect(appController.getAllUsers(req, res)).rejects.toThrow(message);
73             done();
74         });
75     });
76 });

配置vscode调试

 1 {
 2     // 使用 IntelliSense 了解相关属性。
 3     // 悬停以查看现有属性的描述。
 4     // 欲了解更多信息,请访问: https://go.microsoft.com/fwlink/?linkid=830387
 5     "version": "0.2.0",
 6     "configurations": [
 7         {
 8             "name": "Debug TypeScript",
 9             "type": "node",
10             "request": "launch",
11             "env": {
12                 "NODE_ENV": "development"
13             },
14             "runtimeExecutable": "nodemon",
15             "restart": true,
16             "args": [
17                 "${workspaceRoot}/src/main.ts"
18             ],
19             "runtimeArgs": [
20                 "--config",
21                 " nodemon-debug.json",
22                 "--nolazy",
23                 "-r",
24                 "ts-node/register"
25             ],
26             "sourceMaps": true,
27             "disableOptimisticBPs": true,
28             "cwd": "${workspaceRoot}",
29             "protocol": "inspector",
30             "console": "integratedTerminal",
31             "internalConsoleOptions": "neverOpen"
32         },
33         {
34             "type": "node",
35             "request": "launch",
36             "name": "Debug Jest Tests",
37             "program": "${workspaceFolder}/node_modules/.bin/jest",
38             "args": [
39                 "-r tsconfig-paths/register",
40                 "-r ts-node/register",
41                 "--runInBand"
42             ],
43             "console": "integratedTerminal",
44             "internalConsoleOptions": "neverOpen",
45             "disableOptimisticBPs": true,
46             "skipFiles": [
47                 "<node_internals>/**"
48             ],
49         },
50         {
51             "type": "node",
52             "request": "launch",
53             "name": "Debug Jest File",
54             "program": "${workspaceFolder}/node_modules/.bin/jest",
55             "args": [
56                 "${fileBasenameNoExtension}",
57                 "-r tsconfig-paths/register",
58                 "-r ts-node/register",
59                 "--runInBand"
60             ],
61             "console": "integratedTerminal",
62             "internalConsoleOptions": "neverOpen",
63             "disableOptimisticBPs": true,
64         },
65     ]
66 }