#javascript #node.js #unit-testing #sequelize.js #supertest
Вопрос:
Я создаю новый проект и пытаюсь использовать TDD в качестве методологии по умолчанию и пытаюсь применить ее с помощью интеграционного теста.
Дело в том, что я хочу получить всех пользователей из своей базы данных.
//controller.js
const UserService = require('../services/user');
module.exports = {
// corresponds to /users
getAllUsers: async (req, res, next) => {
const users = await UserService.fetchAllUsers();
res.send(users);
},
};
const models = require('../database/models/index'); // I tried also with destructuring
module.exports = {
fetchAllUsers: async () => models.user.findAll(),
};
и мой фактический файл теста выглядит так
const request = require('supertest');
const SequelizeMock = require('sequelize-mock');
const app = require('..');
const dbMock = new SequelizeMock();
const models = require('../src/database/models/index');
jest.mock('../src/database/models/index', () => ({
user: jest.fn(),
}));
models.user.mockImplementation(() => {
const UserMock = dbMock.define('user', {});
UserMock.$queueResult(UserMock.build({
username: 'username',
mail: 'myMail@myMail.com',
}));
return UserMock;
});
describe('Demo test', () => {
it('should respond to users route', (done) => {
request(app)
.get('/users')
.end((err, res) => {
expect(err).toBeNull();
expect(res.status).toBe(200);
expect(res.json).toBe('object');
done();
});
});
});
Все это на самом деле работает, но когда я пытаюсь издеваться над пользователем, я TypeError: models.user.findAll is not a function
Мне нужно заменить model.user значением UserMock.
Есть ли вообще способ это сделать? или я должен просто поиздеваться над Финдаллом, как
jest.mock('../src/database/models/index', () => ({
user: () => ({ findAll: jest.fn() }),
}));
``
Комментарии:
1. Смогли ли вы найти решение для этого? Я сталкиваюсь с той же проблемой.
2. Да, позвольте мне написать решение для вас.
Ответ №1:
В данном случае я издевался не над тем, над чем хотел.
Если вы хотите поиздеваться над моделями, все, что вам нужно сделать, это использовать SpyOn
как
const { sequelize, Report, User } = require('../../database/models/index');
describe("my test", () => {
it("should just mock", () => {
jest.SpyOn(Report, "count").mockResolvedOnce(6);
})
})
В том случае, если вам нужно поиздеваться над вашим сервисом
сначала создайте функции jest, чтобы разрешить доступ из-за пределов вашего макета, а затем издевайтесь над ним с помощью «двойного вызова класса».
const BaseService = require('../BaseService');
const mockFecthOne = jest.fn();
jest.mock('../BaseService',
() => jest.fn().mockImplementation(
() => ({
fetchOne: mockFetchOne,
}),
));
// inside your test just
BaseService().fetchOne.mockResolvedOnce({....})
и это все, надеюсь, сработает.
Комментарии:
1. Это полезно @Julian Mendez. Спасибо.