我将使用jestjs 作为测试框架。
软件包版本:
"sequelize": "^5.21.3"
"jest": "^24.9.0"
"typescript": "^3.9.6"
"ts-jest": "^24.3.0"
单元测试解决方案:
interfaces.ts:
export interface ICoordinates {
type: string;
coordinates: number[];
}
export default interface ILocation {
id: string;
coordinates: ICoordinates;
description?: string | undefined | null;
name: string;
type_id: number;
owner: string;
}
model.ts:
import { sequelize } from '../../db';
import { Model, DataTypes } from 'sequelize';
import ILocation, { ICoordinates } from './interfaces';
export class Location extends Model implements ILocation {
public id!: string;
public coordinates!: ICoordinates;
public description: string | undefined | null;
public name!: string;
public type_id!: number;
public owner!: string;
}
Location.init(
{
id: { type: DataTypes.TEXT, primaryKey: true, allowNull: false },
coordinates: { type: DataTypes.GEOMETRY('POINT', 4326), allowNull: false },
description: { type: DataTypes.TEXT },
name: { type: DataTypes.STRING, allowNull: false },
type_id: { type: DataTypes.NUMBER, allowNull: false },
owner: { type: DataTypes.TEXT, allowNull: false },
},
{
tableName: 'location',
sequelize,
timestamps: false,
},
);
db.ts:
import { Sequelize } from 'sequelize';
import dotenv from 'dotenv';
const dotenvConfigOutput = dotenv.config();
if (dotenvConfigOutput.error) {
console.error(dotenvConfigOutput.error);
process.exit(1);
}
const envVars = dotenvConfigOutput.parsed!;
console.log(envVars);
const sequelize = new Sequelize({
dialect: 'postgres',
host: envVars.POSTGRES_HOST,
username: envVars.POSTGRES_USER,
password: envVars.POSTGRES_PASSWORD,
database: envVars.POSTGRES_DB,
port: Number.parseInt(envVars.POSTGRES_PORT, 10),
define: {
freezeTableName: true,
timestamps: false,
},
pool: {
max: 10,
min: 0,
idle: 10 * 1000,
},
});
export { sequelize };
model.test.ts:
import { DataTypes } from 'sequelize';
const mSequelize = {};
jest.mock('../../db', () => {
return { sequelize: mSequelize };
});
const modelStaticMethodMocks = {
init: jest.fn(),
};
jest.mock('sequelize', () => {
class MockModel {
public static init(attributes, options) {
modelStaticMethodMocks.init(attributes, options);
}
}
return {
...jest.requireActual('sequelize'),
Model: MockModel,
};
});
describe('62584898', () => {
it('should pass', async () => {
await import('./model');
expect(modelStaticMethodMocks.init).toBeCalledWith(
{
id: { type: DataTypes.TEXT, primaryKey: true, allowNull: false },
coordinates: { type: DataTypes.GEOMETRY('POINT', 4326), allowNull: false },
description: { type: DataTypes.TEXT },
name: { type: DataTypes.STRING, allowNull: false },
type_id: { type: DataTypes.NUMBER, allowNull: false },
owner: { type: DataTypes.TEXT, allowNull: false },
},
{
tableName: 'location',
sequelize: mSequelize,
timestamps: false,
},
);
});
});
单元测试结果:
PASS src/examples/stackoverflow/62584898/model.test.ts
62584898
✓ should pass (463ms)
----------|----------|----------|----------|----------|-------------------|
File | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s |
----------|----------|----------|----------|----------|-------------------|
All files | 100 | 100 | 100 | 100 | |
model.ts | 100 | 100 | 100 | 100 | |
----------|----------|----------|----------|----------|-------------------|
Test Suites: 1 passed, 1 total
Tests: 1 passed, 1 total
Snapshots: 0 total
Time: 2.215s, estimated 5s