javascript - 如何在具有私有方法的 Jest 中模拟 http 方法
问题描述
我正在为如何模拟以下功能而苦苦挣扎。我需要模拟这两种方法:getAllBookInCategory
,deleteBookInCategory
公共方法调用私有方法,我假设我不必测试私有方法,只调用公共方法并验证私有方法被调用。这是对的吗?
公共方法:getAllBookInCategory
,deleteBookInCategory
私有方法:makeRequest
import rp from "request-promise-native";
export class BookService {
@param bookCategory id of book category
@param boooks list of books
public static async getAllBookInCategory(bookCategory: string) {
try {
const neededInfo = {
url: `https://${process.env.BOOK_HOST}/bookapi/${process.env.BOOKAPI_VERSION}/iterative/bookCategory/${ bookCategory }/books/all `,
method: 'GET',
}
const result = await BookService.makeRequest(bookCategory, neededInfo);
return rp(result);
} catch(error) {
Console.log(`Failed to get All Books in given category ${error}`)
}
}
public static async deleteBookInCategory(bookCategory: string, books: string[]) {
try{
const neededInfo = {
url: `https://${process.env.BOOK_HOST}/bookapi/${process.env.BOOKAPI_VERSION}/ iterative /bookCategory/${ bookCategory }/books/bookDelete?books=${books.join()}`,
method: 'DELETE',
}
const result = await BookService.makeRequest(bookCategory, neededInfo);
return rp(result);
} catch(error) {
Console.log(`Failed to delete books from category: ${error}`)
}
}
private static async makeRequest(bookCategory: string, neededInfo: any, bodydata?: any) {
const authValue = await BookService.getAuthValue(bookCategory, neededInfo);
return {
method: neededInfo.method,
url: neededInfo.url,
headers: {
Host: process.env.BOOK_HOST,
Authorization: authValue,
},
body: bodydata,
json: true
};
}
}
解决方案
这是方法的单元测试解决方案getAllBookInCategory
。您的代码有问题,您应该使用return await rp(result)
而不是使用return rp(result)
.
BookService.ts
:
import rp from 'request-promise-native';
export class BookService {
public static async getAllBookInCategory(bookCategory: string) {
try {
const neededInfo = {
url: `https://${process.env.BOOK_HOST}/bookapi/${process.env.BOOKAPI_VERSION}/iterative/bookCategory/${bookCategory}/books/all`,
method: 'GET',
};
const result = await BookService.makeRequest(bookCategory, neededInfo);
return await rp(result);
} catch (error) {
console.log(`Failed to get All Books in given category ${error}`);
}
}
public static async deleteBookInCategory(bookCategory: string, books: string[]) {
try {
const neededInfo = {
url: `https://${process.env.BOOK_HOST}/bookapi/${
process.env.BOOKAPI_VERSION
}/iterative/bookCategory/${bookCategory}/books/bookDelete?books=${books.join()}`,
method: 'DELETE',
};
const result = await BookService.makeRequest(bookCategory, neededInfo);
return rp(result);
} catch (error) {
console.log(`Failed to delete books from category: ${error}`);
}
}
private static async makeRequest(bookCategory: string, neededInfo: any, bodydata?: any) {
const authValue = await BookService.getAuthValue(bookCategory, neededInfo);
return {
method: neededInfo.method,
url: neededInfo.url,
headers: {
Host: process.env.BOOK_HOST,
Authorization: authValue,
},
body: bodydata,
json: true,
};
}
private static async getAuthValue(catetory, info) {
return 'authvalue';
}
}
BookService.test.ts
:
import { BookService } from './BookService';
import rp from 'request-promise-native';
jest.mock('request-promise-native', () => jest.fn());
describe('BookService', () => {
afterEach(() => {
jest.resetAllMocks();
jest.restoreAllMocks();
});
describe('#getAllBookInCategory', () => {
beforeEach(() => {
process.env.BOOK_HOST = 'example.com';
process.env.BOOKAPI_VERSION = 'v1';
});
afterEach(() => {
process.env.BOOK_HOST = '';
process.env.BOOKAPI_VERSION = '';
});
it('should make request correctly', async () => {
const mAuthvalue = 'mocked auth value';
jest.spyOn(BookService as any, 'getAuthValue').mockResolvedValueOnce(mAuthvalue);
const mResponse = 'success';
rp.mockResolvedValueOnce(mResponse);
const actual = await BookService.getAllBookInCategory('programming');
expect(actual).toEqual(mResponse);
expect(rp).toBeCalledWith({
method: 'GET',
url: 'https://example.com/bookapi/v1/iterative/bookCategory/programming/books/all',
headers: {
Host: 'example.com',
Authorization: mAuthvalue,
},
body: undefined,
json: true,
});
});
it('should print an error when make request failed', async () => {
const mAuthvalue = 'mocked auth value';
jest.spyOn(BookService as any, 'getAuthValue').mockResolvedValueOnce(mAuthvalue);
const logSpy = jest.spyOn(console, 'log');
const mError = new Error('Internal server error');
rp.mockRejectedValueOnce(mError);
await BookService.getAllBookInCategory('programming');
expect(rp).toBeCalledWith({
method: 'GET',
url: 'https://example.com/bookapi/v1/iterative/bookCategory/programming/books/all',
headers: {
Host: 'example.com',
Authorization: mAuthvalue,
},
body: undefined,
json: true,
});
expect(logSpy).toBeCalledWith(`Failed to get All Books in given category ${mError}`);
});
});
});
带有覆盖率报告的单元测试结果:
PASS src/stackoverflow/59315311/BookService.test.ts
BookService
#getAllBookInCategory
✓ should make request correctly (9ms)
✓ should print an error when make request failed (8ms)
console.log node_modules/jest-mock/build/index.js:860
Failed to get All Books in given category Error: Internal server error
----------------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------------|----------|----------|----------|----------|-------------------|
All files | 73.91 | 100 | 60 | 72.22 | |
BookService.ts | 73.91 | 100 | 60 | 72.22 | 21,28,30,32,52 |
----------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 2 passed, 2 total
Snapshots: 0 total
Time: 5.662s, estimated 13s
您可以deleteBookInCategory
以相同的方式测试方法。
源代码:https ://github.com/mrdulin/jest-codelab/tree/master/src/stackoverflow/59315311
推荐阅读
- karate - 空手道是否支持 CI 环境中的无头测试(gitlab CI)
- discord.py - 检查反应 Discord.py
- javascript - 如何消除菜单项与其下拉菜单之间的差距?
- html - 按下选项卡时,NVDA 在初始页面加载时跳过第一个可聚焦元素
- airflow - DAG 未暂停后气流调度旧任务
- git - 带有 npm 包的 git 同步存储库?
- c# - 我应该将 ToUpper() 方法放在代码中的什么位置才能生效?
- spring - Spring Cloud Contract - 混合 http 和消息传递
- python - 检查用户是否在模型中并在重新注册之前阻止的条件
- java - 正则表达式找不到匹配项 - .find() 和 .matches() 之间的区别有错吗?