I wrote my test code named test.test.ts
. This require testUtils.ts
as client
and call createClient()
and removeClient()
.
test('test', async () => {
let client = require('../testUtils')
expect(1).toBe(1)
jest.resetModules()
await client.createClient()
await client.removeClient()
let detector = new LeakDetector(client)
console.log(await detector.isLeaking())
client = null
jest.resetModules()
console.log(await detector.isLeaking())
global.gc()
})
And here is testUtils.ts
. This file require and use some modules. After all job I call removeClient()
in test.test.ts
file. So I expect all of modules must be garbage collected. But they didn't...
import LeakDetector from 'jest-leak-detector'
export let testClient = null
export let query = null
export let mutate = null
let server = null
let {ApolloServer} = require('apollo-server-express')
let {createTestClient} = require('apollo-server-testing')
let jwt = require('jsonwebtoken')
let {Config} = require('./config')
let {db} = require('my sequelize model')
let {basicDefs, mutationDefs} = require('./defs')
let {AuthDirective} = require('./directives')
let {resolvers} = require('./resolvers')
export const generateToken = async () => {
const user = await db.BlahBlah.findOne({
attributes: ['BlahBlah1', 'BlahBlah2'],
where: {
username: 'BlahBlah',
},
})
return jwt.sign({BlahBlah: BlahBlah, BlahBlah: BlahBlah2}, BlahBlah3)
}
export const createClient = async () => {
if (!testClient) {
server = new ApolloServer({
typeDefs: [basicDefs, mutationDefs],
resolvers,
schemaDirectives: {
auth: AuthDirective,
},
engine: false,
context: {
req: {
headers: {
authorization: `BlahBlah ${await generateToken()}`,
},
},
},
formatError: (err) => {
if (err.message.startsWith('jwt must be provided')) {
return new Error('no login information')
} else return new Error(err.message)
},
})
testClient = createTestClient(server)
query = testClient.query
mutate = testClient.mutate
}
}
export const removeClient = async () => {
jest.resetModules()
await server.stop()
let detector = new LeakDetector(testClient)
console.log(await detector.isLeaking())
testClient = null
global.gc()
console.log(await detector.isLeaking())
detector = new LeakDetector(mutate)
console.log(await detector.isLeaking())
mutate = null
global.gc()
console.log(await detector.isLeaking())
detector = new LeakDetector(query)
console.log(await detector.isLeaking())
query = null
global.gc()
console.log(await detector.isLeaking()) // here
detector = new LeakDetector(ApolloServer)
console.log(await detector.isLeaking())
ApolloServer = null
global.gc()
console.log(await detector.isLeaking()) // here
detector = new LeakDetector(server)
console.log(await detector.isLeaking())
server = null
global.gc()
console.log(await detector.isLeaking())
detector = new LeakDetector(createTestClient)
console.log(await detector.isLeaking())
createTestClient = null
global.gc()
console.log(await detector.isLeaking())
detector = new LeakDetector(jwt)
console.log(await detector.isLeaking())
jwt = null
global.gc()
console.log(await detector.isLeaking()) // here
detector = new LeakDetector(Config)
console.log(await detector.isLeaking())
Config = null
global.gc()
console.log(await detector.isLeaking()) // here
detector = new LeakDetector(db)
console.log(await detector.isLeaking())
db = null
global.gc()
console.log(await detector.isLeaking()) // here
detector = new LeakDetector(basicDefs)
console.log(await detector.isLeaking())
basicDefs = null
global.gc()
console.log(await detector.isLeaking()) // here
detector = new LeakDetector(mutationDefs)
console.log(await detector.isLeaking())
mutationDefs = null
global.gc()
console.log(await detector.isLeaking()) // here
detector = new LeakDetector(AuthDirective)
console.log(await detector.isLeaking())
AuthDirective = null
global.gc()
console.log(await detector.isLeaking())
detector = new LeakDetector(resolvers)
console.log(await detector.isLeaking())
resolvers = null
global.gc()
console.log(await detector.isLeaking())
}
I expected each second console.log print false
because I removed references by assigning null and requested garbage collection, but some console.log(marked // here
) print true
.
Plus, I got this error when I ran node --expose-gc ./node_modules/.bin/jest --logHeapUsage --detectLeaks -- test.test.ts
EXPERIMENTAL FEATURE!
Your test suite is leaking memory. Please ensure all references are cleaned.
There is a number of things that can leak memory:
- Async operations that have not finished (e.g. fs.readFile).
- Timers not properly mocked (e.g. setInterval, setTimeout).
- Keeping references to the global scope.
at onResult (node_modules/@jest/core/build/TestScheduler.js:190:18)
at node_modules/@jest/core/build/TestScheduler.js:304:17
at node_modules/emittery/index.js:260:13
at Array.map (<anonymous>)
at Emittery.Typed.emit (node_modules/emittery/index.js:258:23)
Is there anyone who can explain this and know how solve this problem?
Thank you for your time.
Aucun commentaire:
Enregistrer un commentaire