typedi icon indicating copy to clipboard operation
typedi copied to clipboard

fix: Constructor Injection fail in vitest/jest

Open zhangfisher opened this issue 1 year ago • 3 comments

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

zhangfisher avatar May 04 '23 01:05 zhangfisher

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);
  }

}

abhayshiravanthe avatar May 15 '23 13:05 abhayshiravanthe

This is not a solution Due to the inability to inject through construction, if unit testing is required, construction injection can only be abandoned.

zhangfisher avatar May 16 '23 09:05 zhangfisher

The microsofts DI for typescript, tsyringe, can prepare a separate constructor that hides injections within it and wraps the actual constructor.

mt3o avatar Jun 27 '23 08:06 mt3o