# #node.js #typescript #firebase #unit-testing #jestjs
Вопрос:
Я создаю модульные тесты, но я могу найти способ имитировать функции firebase и уточнять тип возвращаемого значения при их вызове. Ниже я опубликовал то, что я хочу высмеять(account.service.ts), и какой тест у меня есть в настоящее время. Я хочу поиздеваться и указать, что должно быть возвращено с помощью администратора… (он же задает значение объекта resp).
импорт * в качестве администратора из «firebase-администратор»;
учетная запись.сервис.ts
const resp = admin
.auth()
.createUser({
email: registerDto.email,
emailVerified: false,
password: registerDto.password,
displayName: registerDto.displayName,
disabled: false,
})
.then(
(userCredential): Account => ({
uid: userCredential.uid,
email: userCredential.email,
emailVerified: userCredential.emailVerified,
displayName: userCredential.displayName,
message: 'User is successfully registered!',
}),
)
.catch((error) => {
// eslint-disable-next-line max-len
throw new HttpException(`${'Bad Request Error creating new user: '}${error.message}`, HttpStatus.BAD_REQUEST);
});
учетная запись.сервис.спецификация.ts
describe('61396089', () => {
afterEach(() => {
jest.restoreAllMocks();
});
const obj = {
uid: 'uid',
email: 'email',
emailVerified: 'emailVerified',
displayName: 'displayName',
message: 'User is successfully registered!',
};
const jestAdminMock = {
admin: () => ({
auth: () => ({
createUser: () => ({
then: () => ({
catch: () => obj,
}),
}),
}),
}),
};
it('should pass', () => {
const mockDataTable = {
admin: jest.fn().mockReturnThis(),
auth: jest.fn().mockReturnThis(),
createUser: jest.fn().mockReturnThis(),
then: jest.fn().mockReturnThis(),
catch: jest.fn().mockReturnValueOnce(obj),
};
jest.spyOn(jestAdminMock, 'admin').mockImplementationOnce(() => mockDataTable);
const actual = service.registerUser(registerDTO);
expect(actual).toBe(obj);
});
});
});
Комментарии:
1. Откуда берется этот
admin
предмет?2. импорт * в качестве администратора из «firebase-администратор»;
Ответ №1:
Мне удалось провести тест, подобный этому примеру
Это и есть функция
import admin from 'firebase-admin'
admin.initializeApp({
credential: admin.credential.cert(credentials),
})
const createClosure = (admin) => {
if (!admin) {
throw new Error(Errors.FIREBASE_ADMIN_SDK_NOT_PROVIDED)
}
return (data) => {
if (
data amp;amp;
!Array.isArray(data) amp;amp;
typeof data === 'object' amp;amp;
Object.keys(data).length > 0
) {
const { firstName, lastName } = data
const displayName = `${firstName} ${lastName}`
return admin.auth().createUser({ ...data, displayName })
}
throw new Error(Errors.INVALID_DATA)
}
}
/*
.....
*/
const create = createClosure(admin)
export { create, createClosure }
Это тестовый пример
import { createClosure } from "../path/to/function"
describe('createClosure', () => {
it('should be a function', () => {
expect(typeof createClosure).toBe('function')
})
describe('when admin is not provided', () => {
it('should throw "Firebase Admin SDK not provided"', () => {
const expected = Errors.FIREBASE_ADMIN_SDK_NOT_PROVIDED
expect(() => createClosure()).toThrow(expected)
})
})
describe('when admin is provided', () => {
describe('when data is invalid', () => {
const createUser = jest.fn()
const admin = {
auth: () => ({
createUser,
}),
}
const data1 = 123
const data2 = 'hello'
const data3 = ['a', 'b', 'c']
const data4 = {}
it('should throw "Invalid data"', () => {
expect(() => createClosure(admin)()).toThrow(Errors.INVALID_DATA)
expect(() => createClosure(admin)(data1)).toThrow(Errors.INVALID_DATA)
expect(() => createClosure(admin)(data2)).toThrow(Errors.INVALID_DATA)
expect(() => createClosure(admin)(data3)).toThrow(Errors.INVALID_DATA)
expect(() => createClosure(admin)(data4)).toThrow(Errors.INVALID_DATA)
})
})
describe('when data is valid', () => {
const data = {
firstName: 'Alice',
lastName: 'Alley',
foo: 'bar',
baz: {
boo: 'bii',
buu: 'byy',
},
}
describe('when createUser rejects', () => {
const e = new Error('Error happened!')
const createUser = jest.fn().mockRejectedValue(e)
const admin = {
auth: () => ({
createUser,
}),
}
const create = createClosure(admin)
it('should call createUser once', async () => {
try {
await createUser(data)
} catch (error) {}
expect(createUser).toBeCalledTimes(1)
expect(createUser).toBeCalledWith({ ...data })
})
it('should reject', async () => {
await expect(create(data)).rejects.toEqual(e)
})
})
describe('when save resolves', () => {
const expected = {
baz: { boo: 'bii', buu: 'byy' },
displayName: 'Alice Alley',
lastName: 'Alley',
}
const displayName = `${data.firstName} ${data.lastName}`
const createUser = jest.fn().mockResolvedValue(expected)
const admin = {
auth: () => ({
createUser,
}),
}
const create = createClosure(admin)
it('should call save once', async () => {
try {
await create(data)
} catch (error) {}
expect(createUser).toBeCalledTimes(1)
expect(createUser).toBeCalledWith({ ...data, displayName })
})
it('should resolve', async () => {
const result = await create(data)
expect(result).toMatchObject(expected)
})
})
})
})
})
Комментарии:
1. Большое спасибо. Я собираюсь использовать это в качестве ссылки и посмотреть, смогу ли я выполнить свои тесты. Я закрою вопрос, если мне удастся решить задачу тестирования.