-
Notifications
You must be signed in to change notification settings - Fork 0
/
mockMySql.ts
88 lines (78 loc) · 2.75 KB
/
mockMySql.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
import { DeepMockProxy, mockDeep } from 'jest-mock-extended'
import type { Pool, PoolConnection } from 'mysql2/promise'
import { wrapUnknownError } from '@kanziw/error'
import { MySql, mysql } from '../index'
type MockMySql = DeepMockProxy<Pool> & {
_mockPoolConnection: DeepMockProxy<PoolConnection>,
};
type MockMySqlCallOption = { withBeginTransaction?: boolean };
type MockMySqlHelper<Database> = {
db: MySql<Database>;
mockMySqlCall: <Response>(
expectedSql: string,
args: unknown[],
resp: Response | Response[] | Error,
options?: MockMySqlCallOption,
) => void;
checkExecutedSqls: () => void;
}
export const createMockMySqlHelper = <Database>(): MockMySqlHelper<Database> => {
const mockMySql = mockDeep<Pool>() as MockMySql
const mockPoolConnection = mockDeep<PoolConnection>()
mockMySql.getConnection.mockImplementation(() => Promise.resolve(mockPoolConnection))
mockMySql._mockPoolConnection = mockPoolConnection
const sqlAndArgs: Array<[string, unknown[]]> = []
let transactionCount = 0
return {
db: mysql<Database>(mockMySql),
mockMySqlCall: (
expectedSql,
args,
resp,
{ withBeginTransaction }: MockMySqlCallOption = { withBeginTransaction: false },
): void => {
if (withBeginTransaction) {
transactionCount += 1
}
sqlAndArgs.push([expectedSql, args])
if (resp instanceof Error) {
mockMySql._mockPoolConnection.execute.mockRejectedValueOnce(resp)
return
}
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
mockMySql._mockPoolConnection.execute.mockResolvedValueOnce([resp])
},
checkExecutedSqls: () => {
try {
mockMySql._mockPoolConnection.execute.mock.calls.forEach((call, idx) => {
try {
expect(call).toEqual(sqlAndArgs[idx])
} catch (unknownErr: unknown) {
const err = wrapUnknownError(unknownErr)
err.name = `${err.name} at idx: ${idx}`
throw err
}
})
expect(mockMySql._mockPoolConnection.execute.mock.calls.length).toBe(sqlAndArgs.length)
expect(mockMySql._mockPoolConnection.beginTransaction.mock.calls.length)
.toBe(transactionCount)
mockMySql._mockPoolConnection.execute.mockClear()
mockMySql._mockPoolConnection.beginTransaction.mockClear()
sqlAndArgs.splice(0)
transactionCount = 0
} catch (err: unknown) {
console.log(`
Invalid MySQL Mocking Founded. Executed sqls:
${mockMySql._mockPoolConnection.execute.mock.calls
.map(([executedSql]) => ` - ${executedSql}`)
.join('\n')}`)
throw err
}
},
}
}
export class FakeDuplicateError extends Error {
errno = 1062
message = 'Mocked Duplicate Error'
}