我如何测试此javascript模块代码,我的测试通过了,但是甚至无法涵盖Promise.all或anycode(尝试一次执行一个步骤),我已经尝试过此操作(请检查图片以了解覆盖范围):< / p>
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();
})
}
}
my version:
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, {}])
});
})
答案 0 :(得分:0)
这是解决方案,我模拟导入的模块,目录结构为:
.
├── 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
完整的代码演示在这里:https://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/56924299
测试覆盖率报告: