oven-sh / bun

Incredibly fast JavaScript runtime, bundler, test runner, and package manager – all in one
https://bun.sh
Other
74.36k stars 2.78k forks source link

[test] Bun failed to evaluate NestJS dependency injection in Testing Module #15334

Closed deanrih closed 12 hours ago

deanrih commented 13 hours ago

What version of Bun is running?

1.1.36

What platform is your computer?

Linux 6.11.2-4-MANJARO x86_64 unknown

What steps can reproduce the bug?

  1. Create new NestJS app
  2. spec file should already be generated, I'm not referring to test directory, although tests file in the test directory were not detected since it uses -spec instead of _spec and it has a problem that I think is not related to Bun (it requires platform-express despite the main program uses fastify)
  3. Run bun test
  4. It should at least detect one spec file
  5. If not, try to rename the said spec file to *.spec.ts
  6. Test runs
  7. But failed on the generated example of expect(appController.getHello()).toBe("Hello World"); due to Bun failing to resolve the inner expression of return this.appService.getHello():
    
    bun test v1.1.36 (ededc168)

src/module/app/app.spec.ts: 9 | constructor(private readonly appService: AppService) {} 10 | 11 | @Get() 12 | getHello(): string { 13 | this.logger.log("Incoming request."); 14 | return this.appService.getHello(); ^ TypeError: undefined is not an object (evaluating 'this.appService.getHello') at getHello (//src/module/app/app.controller.ts:14:15) at //src/module/app/app.spec.ts:20:25 ✗ AppModule > root > should return "Hello World!" [0.17ms]

0 pass 1 fail Ran 1 tests across 1 files. [237.00ms]


### What is the expected behavior?

The expression `this.appService.getHello` should be properly evaluated, or more precisely, the dependency injection should be resolved properly to inject the `AppService` into the controller so it can evaluate the previous expression which should returns `"Hello World!"` string and pass the test

### What do you see instead?

It failed to resolve the dependency injection and evaluate the expression, resulting the passing test to fail

### Additional information

The spec/testing code looks like this originally:
```ts
import { Test, type TestingModule } from "@nestjs/testing";

import { AppController } from "./app.controller";
import { AppService } from "./app.service";

describe("AppModule", () => {
    let appController: AppController;

    beforeEach(async () => {
        const app: TestingModule = await Test.createTestingModule({
            controllers: [AppController],
            providers: [AppService],
        }).compile();

        appController = app.get<AppController>(AppController);
    });

    describe("root", () => {
        it('should return "Hello World!"', () => {
            expect(appController.getHello()).toBe("Hello World!");
        });
    });
});

when I add some manual code to get AppService manually like:

import { Test, type TestingModule } from "@nestjs/testing";

import { AppController } from "./app.controller";
import { AppService } from "./app.service";

describe("AppModule", () => {
    let appController: AppController;
    let appService: AppService;

    beforeEach(async () => {
        const app: TestingModule = await Test.createTestingModule({
            controllers: [AppController],
            providers: [AppService],
        }).compile();

        appController = app.get<AppController>(AppController);
        appService = app.get<AppService>(AppService);

        console.log(appService.getHello());
    });

    describe("root", () => {
        it('should return "Hello World!"', () => {
            expect(appController.getHello()).toBe("Hello World!");
        });
    });
});

it logs the result of appService.getHello() just fine, which is "Hello World!" but still fail the evaluation and test

bun test v1.1.36 (ededc168)

src/module/app/app.spec.ts:
Hello World!
9 |    constructor(private readonly appService: AppService) {}
10 |
11 |    @Get()
12 |    getHello(): string {
13 |            // this.logger.log("Incoming request.");
14 |            return this.appService.getHello();
^
TypeError: undefined is not an object (evaluating 'this.appService.getHello')
at getHello (/***/src/module/app/app.controller.ts:14:15)
at /***/src/module/app/app.spec.ts:24:25
✗ AppModule > root > should return "Hello World!" [0.18ms]

0 pass
1 fail
Ran 1 tests across 1 files. [237.00ms]
deanrih commented 12 hours ago

Well... after I moved the "emitDecoratorMetadata": true and "experimentalDecorators": true (only the "emitDecoratorMetadata" is important for the test to work) from my tsconfig.test.json and tsconfig.build.json into my main tsconfig.json... it worked...