mysql Sequelize findAll未在sequelize-mock上返回预期输出

vojdkbi0  于 2023-03-22  发布在  Mysql
关注(0)|答案(2)|浏览(109)

我正在尝试使用sequelize-mock对nodejs-express方法进行单元测试。

主计长

const getDetailsByUserId = async (id) => {
        try {
            const userId = id ?? 0;
            const details = await Model.findAll(
                {
                    raw: true,
                    where: { user_id: userId  }
                }
            );
            
            if (details && 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的状态。我检查了返回的数据,它返回了定义的模拟模型的记录。

实际结果:

[
      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.对于这种情况,我可以做些什么来获得预期的结果(空数组)吗?
1.当raw: true被模仿时,它似乎不工作。有没有一种方法可以将结果记录在原始对象上?

**注意:**这只会发生在单元测试中。当访问postman上的端点时,它会返回预期的结果。

ecbunoof

ecbunoof1#

根据文档,findAll()总是会根据选项中的where查询返回一个单一结果的数组。这就是为什么你永远不会得到一个空数组。
查看更多信息:https://sequelize-mock.readthedocs.io/en/stable/api/model/#findalloptions-promisearrayinstance

eqfvzcg8

eqfvzcg82#

查询结果可以使用查询处理器生成。使用$useHandler(handler)-〉QueryInterface模拟查询结果,并使用queryOptions过滤结果。
例如
./models/details.js

module.exports = {};

./controller.js

const Model = require('./models/details');

const getDetailsByUserId = async (id) => {
  const userId = id ?? 0;
  const details = await Model.findAll({
    raw: true,
    where: { user_id: userId },
  });

  if (details && details.length > 0) {
    return {
      status: 200,
      success: true,
      message: 'details found.',
      data: details,
    };
  }

  return {
    status: 404,
    success: false,
    message: 'details not found',
    data: [],
  };
};

module.exports = { getDetailsByUserId };

./controller.test.js

const controller = require('./controller');

jest.mock('./models/details', () => {
  const SequelizeMock = require('sequelize-mock');
  const dbMock = new SequelizeMock();
  const UserMock = dbMock.define('users');
  UserMock.$queryInterface.$useHandler((query, queryOptions) => {
    if (query === 'findAll') {
      if (queryOptions[0].where.user_id === 147) {
        return null;
      }
    }
  });
  return UserMock;
});

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

试验结果:

PASS  src/examples/stackoverflow/69230853/controller.test.js
  69230853
    ✓ should return 404 and an empty array (4ms)

---------------|----------|----------|----------|----------|-------------------|
File           |  % Stmts | % Branch |  % Funcs |  % Lines | Uncovered Line #s |
---------------|----------|----------|----------|----------|-------------------|
All files      |     87.5 |       50 |      100 |     87.5 |                   |
 controller.js |     87.5 |       50 |      100 |     87.5 |                11 |
---------------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        3.363s

软件包版本:

"sequelize-mock": "^0.10.2",
"jest": "^29.5.0",
"sequelize": "^5.21.3",

相关问题