gpt4 book ai didi

javascript - 测试 js 模块,Promise.all

转载 作者:行者123 更新时间:2023-11-29 15:57:54 25 4
gpt4 key购买 nike

如何测试以下 javascript 模块代码?我的测试通过了,但我什至无法涵盖 Promise.all 或任何代码(尝试一次执行一个步骤),我已尝试遵循 How to set a test for multiple fetches with Promise.all using jest 中的建议。

const dbSession = require('server/db/dbSessionModule');
jest.mock('server/db/dbSessionModule');

let controller = {
post: (request, response) => {
const dbSession = new dbSessionModule();
const httpResponse = new HttpResponse();

Promise.all([bcrypt.hash(request.body.payload.password, config.saltRounds), dbSession.connect()])
.then(promiseValues => {
return signupModule.createAccount(dbSession, request.body.payload, promiseValues[0]);
})
.then(responsePayload => {
httpResponse.setSuccess(201, 'ACCOUNT_CREATED', responsePayload);
response.status(httpResponse.status).json(httpResponse);
})
.catch(error => {
console.log(error);
httpResponse.setReject(500, 'ACCOUNT_CREATION_ERROR', error);
response.status(httpResponse.status).json(httpResponse);
})
.finally(() => {
dbSession.release();
});
}
};

describe('Signup Controller', function() {
it('Should hash password and connect user', () => {
const passowrd = 'test';
const hashPassword = '3rasf4#4ad$@!';

const bcrypt = {
hash: jest.fn().mockImplementation(function() {
return Promise.resolve(hashPassword);
})
};

return expect(Promise.all([bcrypt.hash(passowrd, 5), dbSession.connect()])).resolves.toEqual([hashPassword, {}]);
});
});

这是我的覆盖率报告:

code coverage report showing 0% statement coverage, for a function involving Promise.all, with large parts highlighted in red to indicate it not being covered.

最佳答案

这是一个 TypeScript 解决方案。

要转换为 JavaScript,请替换 (dbSessionModule as jest.Mocked<DbSessionModule>)dbSessionModule , (bcrypt as jest.Mocked<typeof bcrypt>)bcrypt , 和 (signupModule as jest.Mocked<typeof signupModule>)signupModule .替换所有对 .ts 的引用与 .js .

我模拟了你导入的模块,目录结构是:

.
├── HttpResponse.ts
├── bcrypt.ts
├── config.ts
├── dbSessionModule.ts
├── index.spec.ts
├── index.ts
└── signupModule.ts

index.ts , 文件将被测试

import HttpResponse from './HttpResponse';
import DbSessionModule from './dbSessionModule';
import bcrypt from './bcrypt';
import signupModule from './signupModule';
import config from './config';

const controller = {
post: (request, response) => {
const dbSession = new DbSessionModule();
const httpResponse = new HttpResponse();

return Promise.all([bcrypt.hash(request.body.payload.password, config.saltRounds), dbSession.connect()])
.then(promiseValues => {
return signupModule.createAccount(dbSession, request.body.payload, promiseValues[0]);
})
.then(responsePayload => {
httpResponse.setSuccess(201, 'ACCOUNT_CREATED', responsePayload);
response.status(httpResponse.status).json(httpResponse);
})
.catch(error => {
console.log(error);
httpResponse.setReject(500, 'ACCOUNT_CREATION_ERROR', error);
response.status(httpResponse.status).json(httpResponse);
})
.finally(() => {
dbSession.release();
});
}
};

export default controller;

单元测试 index.spec.ts :

import '@babel/polyfill';

import controller from './';
import DbSessionModule from './dbSessionModule';
import bcrypt from './bcrypt';
import signupModule from './signupModule';
import config from './config';
import HttpResponse from './HttpResponse';

const request = {
body: {
payload: {
password: ''
}
}
};
const response = {
status: jest.fn().mockReturnThis(),
json: jest.fn().mockReturnThis()
};

const HttpResponseMocked = {
setSuccess: jest.fn().mockImplementation(status => {
HttpResponseMocked.status = status;
}),
setReject: jest.fn().mockImplementation(status => {
HttpResponseMocked.status = status;
}),
status: 0
};

jest.mock('./HttpResponse.ts', () => {
return jest.fn(() => HttpResponseMocked);
});

jest.mock('./bcrypt.ts');

const DbSessionModuleMocked = {
connect: jest.fn(),
release: jest.fn()
};

jest.mock('./dbSessionModule.ts', () => {
return jest.fn(() => DbSessionModuleMocked);
});

jest.mock('./signupModule.ts');

const dbSessionModule = new DbSessionModule();
const httpResponse = new HttpResponse();

describe('controller', () => {
describe('#post', () => {
request.body.payload.password = '123';
config.saltRounds = 'mocked salt';

beforeEach(() => {
(dbSessionModule as jest.Mocked<DbSessionModule>).connect.mockReset();
(dbSessionModule as jest.Mocked<DbSessionModule>).release.mockReset();
});
it('create account correctly', async () => {
(bcrypt as jest.Mocked<typeof bcrypt>).hash.mockResolvedValueOnce('mocked hash');
(dbSessionModule as jest.Mocked<DbSessionModule>).connect.mockResolvedValueOnce({});
(signupModule as jest.Mocked<typeof signupModule>).createAccount.mockResolvedValueOnce({ accountId: 1 });

await controller.post(request, response);

expect(bcrypt.hash).toBeCalledWith('123', 'mocked salt');
expect(dbSessionModule.connect).toBeCalledTimes(1);
expect(signupModule.createAccount).toBeCalledWith(dbSessionModule, { password: '123' }, 'mocked hash');
expect(httpResponse.setSuccess).toBeCalledWith(201, 'ACCOUNT_CREATED', { accountId: 1 });
expect(response.status).toBeCalledWith(201);
expect(response.json).toBeCalledWith(httpResponse);
expect(dbSessionModule.release).toBeCalledTimes(1);
});

it('create account error', async () => {
(bcrypt as jest.Mocked<typeof bcrypt>).hash.mockResolvedValueOnce('mocked hash');
(dbSessionModule as jest.Mocked<DbSessionModule>).connect.mockResolvedValueOnce({});
(signupModule as jest.Mocked<typeof signupModule>).createAccount.mockRejectedValueOnce(new Error('some error'));

await controller.post(request, response);

expect(bcrypt.hash).toBeCalledWith('123', 'mocked salt');
expect(dbSessionModule.connect).toBeCalledTimes(1);
expect(signupModule.createAccount).toBeCalledWith(dbSessionModule, { password: '123' }, 'mocked hash');
expect(httpResponse.setReject).toBeCalledWith(500, 'ACCOUNT_CREATION_ERROR', new Error('some error'));
expect(response.status).toBeCalledWith(500);
expect(response.json).toBeCalledWith(httpResponse);
expect(dbSessionModule.release).toBeCalledTimes(1);
});
});
});

单元测试结果和覆盖率:

 PASS  src/stackoverflow/56924299/index.spec.ts
controller
#post
✓ create account correctly (10ms)
✓ create account error (8ms)

console.log src/stackoverflow/56924299/index.ts:595
Error: some error
at Object.<anonymous> (/Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/56924299/index.spec.ts:80:94)
at step (/Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/56924299/index.spec.ts:32:23)
at Object.next (/Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/56924299/index.spec.ts:13:53)
at /Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/56924299/index.spec.ts:7:71
at new Promise (<anonymous>)
at Object.<anonymous>.__awaiter (/Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/56924299/index.spec.ts:3:12)
at Object.<anonymous> (/Users/elsa/workspace/github.com/mrdulin/jest-codelab/src/stackoverflow/56924299/index.spec.ts:77:32)
at Object.asyncJestTest (/Users/elsa/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/jasmineAsyncInstall.js:102:37)
at resolve (/Users/elsa/workspace/github.com/mrdulin/jest-codelab/node_modules/jest-jasmine2/build/queueRunner.js:43:12)
at new Promise (<anonymous>)

-----------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
-----------------|----------|----------|----------|----------|-------------------|
All files | 85.19 | 100 | 71.43 | 85.19 | |
bcrypt.ts | 50 | 100 | 0 | 50 | 2,3 |
config.ts | 100 | 100 | 100 | 100 | |
index.ts | 100 | 100 | 100 | 100 | |
signupModule.ts | 50 | 100 | 0 | 50 | 2,3 |
-----------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 1.414s, estimated 3s

完成的 TypeScript 演示是 here

测试覆盖率报告:

code coverage report showing 100% of statements covered, and no red highlighting

关于javascript - 测试 js 模块,Promise.all,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56924299/

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