如何使用jest模拟typescript中的外部依赖关系
我正在无可救药地尝试在typescript中模拟firebase管理依赖性以进行单元测试 我的实际功能如下如何使用jest模拟typescript中的外部依赖关系,typescript,unit-testing,jestjs,Typescript,Unit Testing,Jestjs,我正在无可救药地尝试在typescript中模拟firebase管理依赖性以进行单元测试 我的实际功能如下 import {auth} from 'firebase-admin'; async validateUser(payload: string): Promise<User> { try { const resp = await auth().verifyIdToken(payload, true); return await this.userServ
import {auth} from 'firebase-admin';
async validateUser(payload: string): Promise<User> {
try {
const resp = await auth().verifyIdToken(payload, true);
return await this.userService.findByUsername(resp.email);
} catch (e) {
return null;
}
}
但是我得到一个错误,说TypeError:cannotread未定义的属性'mockReturnValue'
如果我理解正确,我将通过调用jest.mock('firebase-admin')
模拟整个firebase-admin
包。因此,我希望能够调用auth函数中的mockReturnValue
并再次模拟verifyIdToken
函数。然而,我甚至不能调用mockReturnValue
,因为奇怪的是它似乎不存在
我需要如何编写代码才能模拟
auth().verifyIdToken()
?这种情况下的问题是auth
和firebase admin
中的类似导出函数被定义为具有Object.defineProperty
的getter。不幸的是,jest.mock
在计算模块时无法看到这些,因此它不会为它们添加mock
您需要在提供给jest.mock
的工厂中模拟auth
(以及您需要的任何同级函数)。下面介绍如何替换第二个代码段中的jest.mock
行:
jest.mock('firebase-admin', () =>
{
const module = jest.createMockFromModule<any>('firebase-admin').default;
module.auth = jest.fn();
return module;
});
jest.mock('firebase-admin',()=>
{
const module=jest.createMockFromModule('firebase-admin')。默认值;
module.auth=jest.fn();
返回模块;
});
您还可以选择在该工厂内模拟
auth
的返回值,以进一步简化代码。这种情况下的问题是auth
和firebase admin
中的类似导出函数被定义为具有对象的getter。defineProperty
。不幸的是,jest.mock
在计算模块时无法看到这些,因此它不会为它们添加mock
您需要在提供给jest.mock
的工厂中模拟auth
(以及您需要的任何同级函数)。下面介绍如何替换第二个代码段中的jest.mock
行:
jest.mock('firebase-admin', () =>
{
const module = jest.createMockFromModule<any>('firebase-admin').default;
module.auth = jest.fn();
return module;
});
jest.mock('firebase-admin',()=>
{
const module=jest.createMockFromModule('firebase-admin')。默认值;
module.auth=jest.fn();
返回模块;
});
您还可以选择在该工厂内模拟
auth
的返回值,以进一步简化代码。用户将模拟工厂与模拟firebase
模块相结合
jest.mock('firebase-admin', () => {
return {
auth: jest.fn(),
}
});
等级库文件的示例:
import { auth } from 'firebase-admin';
import Test from './index';
jest.mock('firebase-admin', () => {
return {
auth: jest.fn(),
}
});
describe("Test", () => {
const email = 'mocked-email@example.com';
const user = { email, username: 'mocked-username' };
let mockedAuth: jest.Mock;
let mockVerifyIdToken: jest.Mock;
let mockUserService: { findByUsername: jest.Mock }; // mock userService
let testInstance: Test;
beforeEach(() => {
mockedAuth = auth as jest.Mock;
mockVerifyIdToken = jest.fn()
mockedAuth.mockReturnValue({
verifyIdToken: mockVerifyIdToken,
});
mockUserService = {
findByUsername: jest.fn(),
};
testInstance = new Test(mockUserService);
});
test("should return user info when pass correct payload", async () => {
const payload = 'mocked-payload';
mockVerifyIdToken.mockResolvedValue({ email });
mockUserService.findByUsername.mockResolvedValue(user);
const result = await testInstance.validateUser(payload);
expect(result).toBe(user);
expect(mockVerifyIdToken).toHaveBeenCalledWith(payload, true);
expect(mockUserService.findByUsername).toHaveBeenCalledWith(email);
});
})
用户向模拟
firebase
模块的模拟工厂开玩笑
jest.mock('firebase-admin', () => {
return {
auth: jest.fn(),
}
});
等级库文件的示例:
import { auth } from 'firebase-admin';
import Test from './index';
jest.mock('firebase-admin', () => {
return {
auth: jest.fn(),
}
});
describe("Test", () => {
const email = 'mocked-email@example.com';
const user = { email, username: 'mocked-username' };
let mockedAuth: jest.Mock;
let mockVerifyIdToken: jest.Mock;
let mockUserService: { findByUsername: jest.Mock }; // mock userService
let testInstance: Test;
beforeEach(() => {
mockedAuth = auth as jest.Mock;
mockVerifyIdToken = jest.fn()
mockedAuth.mockReturnValue({
verifyIdToken: mockVerifyIdToken,
});
mockUserService = {
findByUsername: jest.fn(),
};
testInstance = new Test(mockUserService);
});
test("should return user info when pass correct payload", async () => {
const payload = 'mocked-payload';
mockVerifyIdToken.mockResolvedValue({ email });
mockUserService.findByUsername.mockResolvedValue(user);
const result = await testInstance.validateUser(payload);
expect(result).toBe(user);
expect(mockVerifyIdToken).toHaveBeenCalledWith(payload, true);
expect(mockUserService.findByUsername).toHaveBeenCalledWith(email);
});
})