开玩笑(Nestjs) - 如何模拟方法依赖性?

发布于 2025-02-12 15:14:42 字数 2714 浏览 0 评论 0原文

在下面的代码中,我试图测试“ somemethodotest” 方法,但是应模拟“某些依赖性method” 方法。但是,所证明的方法并不是一个例外“我一定不能被称为!” 每次我玩Jest时都会启动测试...

 FAIL  src/user-files/user-files.service.spec.ts (0.123 s)
  ● SomeClassToTest › test someMethodToTest

    thrown: "I MUST NOT BE CALLED!"

注释: i - 这是Nestjs应用程序; II-使用开玩笑的测试; iii-简化代码以促进理解。

我尝试了很多很多方法...

问题:代码有什么问题? 依赖性”方法被称为

为什么“某些

? 。开玩笑 ]

some-mdl-to-test.service.ts

import { Injectable } from '@nestjs/common';
import { SomeDependencyClass } from './some-dependency-mdl';

@Injectable()
export class SomeClassToTest {
  async someMethodToTest(someMethodToTestArg: string): Promise<string> {
    const someDependencyMethodOutput: string = await new SomeDependencyClass().someDependencyMethod(someMethodToTestArg);
    return someDependencyMethodOutput;
  }
}

某种依赖性mdl.ts

export class SomeDependencyClass {
  async someDependencyMethod(someDependencyMethodArg: string): Promise<string> {
    throw 'I MUST NOT BE CALLED!';
    // ...
    // SOME LOGIC!
    // ...
    return "SOME_VALUE_A";
  }
}

mdl-to-test.service.spec.ts

import { Test, TestingModule } from '@nestjs/testing';
import { SomeClassToTest } from './some-mdl-to-test.service';
import { SomeDependencyClass } from './some-dependency-mdl';

describe('SomeClassToTest', () => {
  let someClassToTest: SomeClassToTest;
  let someDependencyClass: SomeDependencyClass;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [SomeClassToTest, SomeDependencyClass],
    }).compile();
    someClassToTest = module.get<SomeClassToTest>(SomeClassToTest);
    someDependencyClass = module.get<SomeDependencyClass>(SomeDependencyClass);
  });

  it('should be defined', () => {
    expect(someClassToTest).toBeDefined();
  });

  it('Test someMethodToTest!', async () => {
    const someDependencyMethodOutputMock = "SOME_VALUE_A";
    const someMethodToTestInputMock = "SOME_VALUE_B";
    const someMethodToTestOutput = "SOME_VALUE_A";
    const someDependencyMethodPromise: Promise<string> = Promise.resolve(someDependencyMethodOutputMock);
    jest.spyOn(someDependencyClass, 'someDependencyMethod').mockImplementation(() => someDependencyMethodPromise);
    const someMethodToTestOutputToCheck = await someClassToTest.someMethodToTest(someMethodToTestInputMock);
    expect(someMethodToTestOutputToCheck).toEqual(someMethodToTestOutput);
  });
});

In the codes below I am trying to test the "someMethodToTest" method, but the "someDependencyMethod" method should be mocked. However, the demonstrated approach is not working as the exception "I MUST NOT BE CALLED!" is being launched every time I run the tests with Jest...

 FAIL  src/user-files/user-files.service.spec.ts (0.123 s)
  ● SomeClassToTest › test someMethodToTest

    thrown: "I MUST NOT BE CALLED!"

NOTES: I - This is a NestJS application; II - Tests using Jest; III - The code is simplified to facilitate understanding.

I've tried many, many approaches...

QUESTION: What is wrong with the code? Why does the "someDependencyMethod" method keep being called? ????

Thanks! ????

[Ref(s).: How to Mock dependencies with Jest ]

some-mdl-to-test.service.ts

import { Injectable } from '@nestjs/common';
import { SomeDependencyClass } from './some-dependency-mdl';

@Injectable()
export class SomeClassToTest {
  async someMethodToTest(someMethodToTestArg: string): Promise<string> {
    const someDependencyMethodOutput: string = await new SomeDependencyClass().someDependencyMethod(someMethodToTestArg);
    return someDependencyMethodOutput;
  }
}

some-dependency-mdl.ts

export class SomeDependencyClass {
  async someDependencyMethod(someDependencyMethodArg: string): Promise<string> {
    throw 'I MUST NOT BE CALLED!';
    // ...
    // SOME LOGIC!
    // ...
    return "SOME_VALUE_A";
  }
}

some-mdl-to-test.service.spec.ts

import { Test, TestingModule } from '@nestjs/testing';
import { SomeClassToTest } from './some-mdl-to-test.service';
import { SomeDependencyClass } from './some-dependency-mdl';

describe('SomeClassToTest', () => {
  let someClassToTest: SomeClassToTest;
  let someDependencyClass: SomeDependencyClass;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [SomeClassToTest, SomeDependencyClass],
    }).compile();
    someClassToTest = module.get<SomeClassToTest>(SomeClassToTest);
    someDependencyClass = module.get<SomeDependencyClass>(SomeDependencyClass);
  });

  it('should be defined', () => {
    expect(someClassToTest).toBeDefined();
  });

  it('Test someMethodToTest!', async () => {
    const someDependencyMethodOutputMock = "SOME_VALUE_A";
    const someMethodToTestInputMock = "SOME_VALUE_B";
    const someMethodToTestOutput = "SOME_VALUE_A";
    const someDependencyMethodPromise: Promise<string> = Promise.resolve(someDependencyMethodOutputMock);
    jest.spyOn(someDependencyClass, 'someDependencyMethod').mockImplementation(() => someDependencyMethodPromise);
    const someMethodToTestOutputToCheck = await someClassToTest.someMethodToTest(someMethodToTestInputMock);
    expect(someMethodToTestOutputToCheck).toEqual(someMethodToTestOutput);
  });
});

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

溇涏 2025-02-19 15:14:42

好吧,问题在于您如何注入依赖项。从某种意义上说,使用您提供的代码,您没有注入依赖项。

如果您的someclasStototest看起来像:

@Injectable()
export class SomeClassToTest {
  constructor(
    @Inject(SomeDependencyClass)
    private readonly someDependencyClass: SomeDependencyClass
  ) {}

  async someMethodToTest(someMethodToTestArg: string): Promise<string> {
    return await this.someDependencyClass.someDependencyMethod(
      someMethodToTestArg
    );
  }
}

您的测试可能看起来像:

describe("SomeClassToTest", () => {
  let someClassToTest: SomeClassToTest;

  const mockReturnValue = "SOME_VALUE_A",
    mockDependencyClass: SomeDependencyClass = {
      someDependencyMethod: async (): Promise<string> => {
        throw new Error("ups");
      },
    };

  beforeEach(() => {
    jest.clearAllMocks();

    jest
      .spyOn(mockDependencyClass, "someDependencyMethod")
      .mockImplementation(async () => mockReturnValue);
  });

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      providers: [
        SomeClassToTest,
        { provide: SomeDependencyClass, useValue: mockDependencyClass },
      ],
    }).compile();

    someClassToTest = module.get(SomeClassToTest);
  });

  it("should be defined", () => {
    expect(someClassToTest).toBeDefined();
  });

  it("Test someMethodToTest!", async () => {
    const someMethodToTestOutputToCheck =
      await someClassToTest.someMethodToTest("something");

    expect(someMethodToTestOutputToCheck).toEqual(mockReturnValue);
  });
});

让我知道是否需要更多澄清:)

通过nest 概述 fastalmentals 应该给您足够的足够来理解上面的代码

Well, the problem is how you are injecting your dependencies. In the sense that, with the code you provided, you are not injecting the dependencies.

If your SomeClassToTest would look like:

@Injectable()
export class SomeClassToTest {
  constructor(
    @Inject(SomeDependencyClass)
    private readonly someDependencyClass: SomeDependencyClass
  ) {}

  async someMethodToTest(someMethodToTestArg: string): Promise<string> {
    return await this.someDependencyClass.someDependencyMethod(
      someMethodToTestArg
    );
  }
}

Your tests could look something like:

describe("SomeClassToTest", () => {
  let someClassToTest: SomeClassToTest;

  const mockReturnValue = "SOME_VALUE_A",
    mockDependencyClass: SomeDependencyClass = {
      someDependencyMethod: async (): Promise<string> => {
        throw new Error("ups");
      },
    };

  beforeEach(() => {
    jest.clearAllMocks();

    jest
      .spyOn(mockDependencyClass, "someDependencyMethod")
      .mockImplementation(async () => mockReturnValue);
  });

  beforeEach(async () => {
    const module = await Test.createTestingModule({
      providers: [
        SomeClassToTest,
        { provide: SomeDependencyClass, useValue: mockDependencyClass },
      ],
    }).compile();

    someClassToTest = module.get(SomeClassToTest);
  });

  it("should be defined", () => {
    expect(someClassToTest).toBeDefined();
  });

  it("Test someMethodToTest!", async () => {
    const someMethodToTestOutputToCheck =
      await someClassToTest.someMethodToTest("something");

    expect(someMethodToTestOutputToCheck).toEqual(mockReturnValue);
  });
});

Let me know if something needs more clarifying :)

Going through Nest overview and fundamentals should give you enough to understand the code above

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文