问题
I'm having a similar problem as in #5164 and this question. Consider the following working test code:
// AccountResolver.test.ts
describe('Account entity', () => {
it('add account', async () => {
await createConnections()
const defaultConnection = getConnection('default')
const actual = await callGraphql(
`mutation {
addAccount(options: {
accountIdentifier: "7csdcd8-8a5f-49c3-ab9a-0198d42dd253"
name: "Jake, Bob (Braine-l’Alleud) JAM"
userName: "Bob.Marley@contoso.com"
}) {
accountIdentifier
name
userName
}
}`
)
expect(actual.data).toMatchObject({
data: {
addAccount: {
accountIdentifier: '7csdcd8-8a5f-49c3-ab9a-0198d42dd253',
name: 'Jake, Bob (Braine-l’Alleud) JAM',
userName: 'Bob.Marley@contoso.com',
},
},
})
await defaultConnection.query(`DELETE FROM Account`)
await defaultConnection.close()
})
})
The code to create a connection and close it should be executed before all tests and after all tests are done, that's why we've added it to globalSetup.ts
and globalTeardown.ts
:
// globalSetup.ts
require('ts-node/register')
import { createConnections } from 'typeorm'
module.exports = async () => {
// console.log('jest setup')
await createConnections()
}
// globalTeardown.ts
require('ts-node/register')
import { getConnection } from 'typeorm'
module.exports = async () => {
const defaultConnection = getConnection('default')
await defaultConnection.close()
}
// AccountResolver.test.ts
describe('Account entity', () => {
it('add account', async () => {
const defaultConnection = getConnection('default')
await defaultConnection.query(`DELETE FROM Account`)
const actual = await callGraphql(
`mutation {
addAccount(options: {
accountIdentifier: "7csdcd8-8a5f-49c3-ab9a-0198d42dd253"
name: "Jake, Bob (Braine-l’Alleud) JAM"
userName: "Bob.Marley@contoso.com"
}) {
accountIdentifier
name
userName
}
}`
)
expect(actual.data).toMatchObject({
data: {
addAccount: {
accountIdentifier: '7csdcd8-8a5f-49c3-ab9a-0198d42dd253',
name: 'Jake, Bob (Braine-l’Alleud) JAM',
userName: 'Bob.Marley@contoso.com',
},
},
})
})
})
Omitting the line require('ts-node/register')
from both files throws this error:
T:\Test\src\it-portal\entity\Account.ts:1 import { ^^^^^^ SyntaxError: Cannot use import statement outside a module
Keeping the require
line in throws:
FAIL src/resolvers/AccountResolver.test.ts × add account (31 ms) ● Account entity › add account ConnectionNotFoundError: Connection "default" was not found.Account entity
Version
"jest": "^26.0.1",
"ts-jest": "^26.1.0",
"ts-node-dev": "^1.0.0-pre.44",
"typescript": "^3.9.5"
Config
// jest.config.js
module.exports = {
preset: 'ts-jest',
globalSetup: './src/test-utils/config/globalSetup.ts',
globalTeardown: './src/test-utils/config/globalTeardown.ts',
setupFiles: ['./src/test-utils/config/setupFiles.ts'],
moduleDirectories: ['node_modules', 'src'],
globals: {
'ts-jest': {
tsConfig: 'tsconfig.json',
diagnostics: {
warnOnly: true,
},
},
},
coverageThreshold: {
global: {
branches: 80,
functions: 80,
lines: 80,
statements: 80,
},
},
coverageReporters: ['json', 'lcov', 'text', 'clover'],
}
Thank you for pointing out my mistakes. As I'm new I tried googling but couldn't really find an answer if this is me not understanding the tool or a bug in the too. Found a similar issue here with a PR.
It seems like the tests are running in a fully isolated environment where they can't access the connection set up within globalSetup
.
Workaround
The only workaround I have found thus far is to add the following code to every test file:
beforeAll(async () => {
await createConnections()
})
afterAll(async () => {
const defaultConnection = getConnection('default')
await defaultConnection.close()
})
回答1:
require('ts-node/register')
shouldn't present in .ts files. They are already processed by TypeScript compiler.
This is not what globalSetup
and globalTeardown
are for. They run in Jest parent process and are evaluated once, while each test suite runs in child processes.
This can be achieved by providing a common setup in setupFilesAfterEnv option:
// jest.setup.ts
...
beforeAll(async () => {
await createConnections()
})
afterAll(async () => {
const defaultConnection = getConnection('default')
await defaultConnection.close()
})
Since Jest tests run in parallel, this will result in multiple database connections. If this is not desirable because of connection limit, Jest runInBand
option needs to be used.
A setup for all tests not desirable because not all test suites need database connection, while they will unconditionally take time and occupy database connection pool. In this case jest.setup.ts can be imported directly in tests that use a database instead of setupFilesAfterEnv
, no need to specify beforeAll
and afterAll
in each suite.
来源:https://stackoverflow.com/questions/62470047/typeorm-connection-default-was-not-found-when-connection-is-created-in-jest-gl