
재고가 들어 왔다고 알림을 줘야하는데 slack을 사용하여 채널에 등록된 사용자들에게 알려줍시다.
참고
> npm i nestjs-slack-webhook
> npm i @slack/client @nestjs/config
SlackConfig 등록 (webhook)
.env file    SLACK_WEBHOOK_URL=https://hooks.slack.com/services/{비밀입니다!}
src/config/slack.config.ts file    import { registerAs } from '@nestjs/config';
    import { SlackOptions } from 'nestjs-slack-webhook';
    export default registerAs(
      'slack',
      (): SlackOptions => ({
        url: process.env.SLACK_WEBHOOK_URL,
      }),
    );
SlackModule Global로 등록
src/app.module.ts file    // ...
    import { ConfigModule, ConfigService } from '@nestjs/config';
    import slackConfig from './config/slack.config';
    import { WatcherModule } from './watcher/watcher.module';
    @Module({
      imports: [
        ConfigModule.forRoot({
          load: [slackConfig],
        }),
        SlackModule.forRootAsync({
          imports: [ConfigModule],
          inject: [ConfigService],
          useFactory: (config) => config.get('slack'),
        }),
        // ...
      ],
      // ...
    })
    export class AppModule {}
  import { Injectable } from '@nestjs/common';
  import { IncomingWebhook, IncomingWebhookSendArguments } from '@slack/client';
  import { InjectSlack } from 'nestjs-slack-webhook';
  @Injectable()
  export class NotifyService {
    constructor(
      @InjectSlack()
      private readonly slack: IncomingWebhook,
    ) {}
    async notify(args: IncomingWebhookSendArguments) {
      return await this.slack.send(args);
    }
  }
WatcherService에 NotifyService를 사용할 겁니다.
우선 NotifyService Mock 객체를 만들어 주자
const mockNotifyService = {
  notify: jest.fn(),
};
그리고 NotifyService를 TestModule에 주입합시다.
describe('WatcherService', () => {
  // ...
  let notifyService: NotifyService;
  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      // ...
      providers: [
        // ...
        { provide: NotifyService, useValue: mockNotifyService }, // <- 주입
      ],
    }).compile();
test 코드를 작성할때 NotifyService를 jest의 spyOn 의 기능으로 메서드 구라를 칩시다.
또한 toHaveBeenCalledTimes, toHaveBeenCalledWith 메서드로 해당 method가 수행 되었는지 체크합시다.
describe('notify()', () => {
  it('should notify to slack', async () => {
    // given
    const requestNotify: IncomingWebhookSendArguments = {
      text: '(test-code) Buy It! Hurry Up!',
    };
    const resultNotify: IncomingWebhookResult = {
      text: 'ok',
    };
    jest
      .spyOn(notifyService, 'notify')
      .mockImplementation(
        async (arg: IncomingWebhookSendArguments) => resultNotify,
      );
    // when
    const result = await watcherService.notify(requestNotify);
    // then
    // expect(notifyService.notify).toHaveBeenCalledTimes(1);
    expect(result).toEqual(resultNotify);
    expect(notifyService.notify).toHaveBeenCalledTimes(1);
    expect(notifyService.notify).toHaveBeenCalledWith(requestNotify);
  });
});
테스트코드를 작동 할 수 있도록 소스 코드를 구현합니다.
@Injectable()
export class WatcherService {
  constructor(
    // ...
    private readonly notifyService: NotifyService,
  ) {}
  // ...
  async notify(requestNotifyToSlack: IncomingWebhookSendArguments) {
    return await this.notifyService.notify(requestNotifyToSlack);
  }
}
그럼 결과로 test를 통과하게 할 수 있게 되었습니다.
 PASS  src/crawler/watcher.service.spec.ts
  WatcherService
    ✓ should be defined (9 ms)
    getHTTPRequest()
      ✓ should request http given url (4 ms)
    parseHtmlAndCheckIsSoldOut()
      ✓ should parse Html And Check Is SoldOut (8 ms)
      ✓ should parse Html And Check Is SoldOut is false (4 ms)
    notify()
      ✓ should notify to slack (2 ms) # <====== 테스트 통과
NotifyService에 대한 테스트코드도 미리 작성해야합니다.