如何让nodemailer在nestjs测试代码中模拟对象或工厂?

h5qlskok  于 2023-02-15  发布在  Node.js
关注(0)|答案(1)|浏览(165)

我在我的NestJS应用程序中使用nodemailer发送电子邮件。为了防止在我运行测试时发送真实的的电子邮件,我想创建一个nodemailer的模拟对象,以便在我的测试中使用。但是,我不知道如何正确地创建这个对象。
当我试图做一个mocking对象时,有“connect ECONNREFUSED 127. 0. 0. 1:587”,这个错误是“nodemailer需要一个访问连接到gmail”,所以它使用docenv代码添加了设置值。

dotenv.config({
  path: path.resolve(`src/config/env/.development.env`),
});

之后,测试成功,并始终发送验证邮件。但我不想在运行测试时发送邮件,并希望使用模拟对象。
除了.env之外,我已经将整个代码上传到CodeSandBox中,所以我希望它对参考有帮助。
源代码(codeSandbox):https://codesandbox.io/p/sandbox/crazy-bouman-2tvq79
用户服务测试代码:https://codesandbox.io/p/sandbox/crazy-bouman-2tvq79?file=%2Fsrc%2Fusers%2Fusers.service.spec.ts&selection=%5B%7B%22endColumn%22%3A4%2C%22endLineNumber%22%3A26%2C%22startColumn%22%3A4%2C%22startLineNumber%22%3A26%7D%5D
电子邮件服务:https://codesandbox.io/p/sandbox/crazy-bouman-2tvq79?file=%2Fsrc%2Femail%2Femail.service.ts&selection=%5B%7B%22endColumn%22%3A4%2C%22endLineNumber%22%3A26%2C%22startColumn%22%3A4%2C%22startLineNumber%22%3A26%7D%5D

uqxowvwt

uqxowvwt1#

你可以从你的UsersService模拟你的EmailService。另外,如果你想测试EmailService,你可以使用jest.mock(),或者你可以把nodemailer作为一个依赖注入到你的服务中,然后你就可以使用Nest的测试模块轻松地模拟它。
UsersService中模拟EmailService

describe('UsersService', () => {
  let module: TestingModule;
  let service: UsersService;
  let sendUserVerficationEmailMock;

  beforeAll(() => {
    dotenv.config({
      path: path.resolve(`src/config/env/.development.env`),
    });
  });

  beforeEach(async () => {
    sendUserVerficationEmailMock = jest
     .fn()
     .mockImplementation(() => console.log('email sent'));

    module = await Test.createTestingModule({
      imports: [
        TypeOrmModule.forRoot({
          type: 'sqlite',
          database: ':memory:',
          entities: [UserEntity],
          synchronize: true,
        }),
        UsersModule,
      ],
    })
      .overrideProvider(EmailService)
      .useValue({
        sendUserVerficationEmail: sendUserVerficationEmailMock,
      })
      .compile();

    service = module.get(UsersService);
    await service.createUser('tom', 'tom@email.com', '!@#$');
  });

  it('should throw Error when email is existed', async () => {
    const result = service.createUser('tom', 'tom@email.com', '!@#$');
    expect(sendUserVerficationEmailMock).toBeCalledTimes(1);
    await expect(result).rejects.toThrowError(
      new UnprocessableEntityException('이미 가입된 이메일 입니다.'),
    );
  });
});

在EmailService中模拟NodeMailer

网上有很多关于如何用jest模拟第三方库的例子,你可以尝试下面提到的不同方法:https://jestjs.io/docs/jest-object.
或者更好的方法(IMO)是将NodeMailer注入到您的服务中,并遵循与我们在上一个示例中相同的方法
您可能还想考虑为NodeMailer使用NestJS Package 器模块,类似于NestJS Mailer,因为它将这些依赖项作为NestJS模块和提供者提供,更容易模拟。

相关问题