typedi
typedi copied to clipboard
fix: Constructor Injection fail in vitest/jest
Description
Constructor Injection fail in vitest/jest Injected with instance ContainerInstance
import 'reflect-metadata';
//import {expect, test} from "vitest"
import {expect, test} from '@jest/globals';
import { Container, Inject, Service, ServiceOptions, Token } from 'typedi';
import { FlexEvent } from 'flex-tools';
@Service({
id:"app",
global:true,
eager:true
})
class App extends FlexEvent{
constructor(
@Inject(WORKSHOP)
public workshop:Workshop
){
super()
}
@Service({
id:"app",
global:true,
eager:true
})
class App extends FlexEvent{
constructor(
@Inject(WORKSHOP)
public workshop:Workshop
){
super()
// workshop === Injected with instance ContainerInstance
}
}
test("构造注入", () => {
let app = Container.get("app") as App
expect(app.workshop).toBeInstanceOf(Workshop)
})
Expected behavior
Injected with instance Workshop
Actual behavior
Injected with instance Workshop ContainerInstance
We found out that when you are using Jest and TypeDI, using @Inject
tag doesn't actually inject dependencies into the class during test execution. A workaround would be to manually add dependency resolution in the class constructor, for example:
class SomeClass {
constructor() {
// Why - for resolvers or classes where Jest can't resolve the injected services
this.emailService = Container.get(EmailService);
}
}
This is not a solution Due to the inability to inject through construction, if unit testing is required, construction injection can only be abandoned.
The microsofts DI for typescript, tsyringe, can prepare a separate constructor that hides injections within it and wraps the actual constructor.