Издевательское продолжение с шуткой и продолжением-издевательство

#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. Спасибо.