Sequelize findAll не возвращает ожидаемый результат на sequelize-макет

#mysql #node.js #unit-testing #mocking #sequelize.js

Вопрос:

Я пытаюсь провести модульное тестирование своего метода nodejs-express с помощью sequelize-mock.

Контроллер

 const getDetailsByUserId = async (id) => {
        try {
            const userId = id ?? 0;
            const details = await Model.findAll(
                {
                    raw: true,
                    where: { user_id: userId  }
                }
            );
            
            if (details amp;amp; details .length > 0) {
                return {
                    status: 200,
                    success: true,
                    message: 'details found.',
                    data: details 
                }
            }
    
            return {
                status: 404,
                success: false,
                message: 'details not found',
                data: []
            }
        } catch (error) {
            return {
                status: 500,
                success: false,
                message: error.message || "An error occurred while getting details.",
                data: null
            }
        }
    }
 

Тест

 jest.mock('../models/details', () => () => {
    const SequelizeMock = require("sequelize-mock");
    const dbMock = new SequelizeMock();
    return dbMock.define('users', [
        {
            id: 1,
            user_id: 123
            name: 'John Doe 1'
        },
        {
            id: 2,
            user_id: 456
            name: 'John Doe 2'
        },
        {
            id: 3,
            user_id: 789
            name: 'John Doe 3'
        }
    ]);
});

test('should return 404 and an empty array', async () => {
            const userId = 147;
            const details = await controller.getDetailsByUserId(userId);

            expect(details.status).toEqual(404);
        });
 

Здесь я всегда получаю статус 200 вместо 404. Я проверил возвращенные данные, и они возвращают записи определенной издевательской модели.

Actual Result:

 [
      fakeModelInstance {
        options: {
          timestamps: true,
          paranoid: undefined,
          createdAt: undefined,
          updatedAt: undefined,
          deletedAt: undefined,
          isNewRecord: true
        },
        _values: {
          '0': [Object],
          '1': [Object],
          '2': [Object],
          user_id: 147,
          id: 1,
          createdAt: 2021-09-18T00:55:25.976Z,
          updatedAt: 2021-09-18T00:55:25.976Z
        },
        dataValues: {
          '0': [Object],
          '1': [Object],
          '2': [Object],
          user_id: 147,
          id: 1,
          createdAt: 2021-09-18T00:55:25.976Z,
          updatedAt: 2021-09-18T00:55:25.976Z
        },
        hasPrimaryKeys: true,
        __validationErrors: []
      }
    ]
 

вопросы:

  1. Могу ли я что-то сделать, чтобы получить ожидаемый результат (пустой массив) для этого сценария?
  2. raw: true кажется, что это не работает, когда над ним издеваются. Есть ли способ зарегистрировать результат на необработанном объекте?

ПРИМЕЧАНИЕ: Это происходит только при модульном тестировании. При доступе к конечной точке на postman он возвращает ожидаемый результат.

Ответ №1:

Согласно документам, findAll() всегда будет возвращать массив одного результата на основе запроса where в параметрах. Вот почему вы никогда не получите пустой массив.

Смотрите больше: https://sequelize-mock.readthedocs.io/en/stable/api/model/#findalloptions-promisearrayinstance

Комментарии:

1. Спасибо за ответ. Я забыл упомянуть, что мое предложение where отсутствует/доступно в издевательской бд. Как вы можете видеть в тестовой части, я нахожу идентификатор пользователя 147, но в издевательской базе данных у меня есть только 123, 456 и 789. Поэтому я ожидаю, что результат теста не пройдет/получит статус 404.