在 NestJs 中使用 jest 的 toHaveBeenCalledWith 模拟 Date.Now。

3
我正在尝试使用jest在我的nestjs应用程序中模拟对Date.now的调用。
我有一个存储库方法,可以软删除资源。
async destroy(uuid: string): Promise<boolean> {
  await this.userRepository.update({ userUUID: uuid }, { deletedDate: Date.now() });
  return true;
}

为了进行软删除,我们只需添加一个时间戳,表示何时请求将其删除。

在这里和其他网站上进行了一些讨论后,我想出了这个测试。

  describe('destroy', () => {
    it('should delete a user schemas in the user data store', async () => {
      const getNow = () => Date.now();
      jest
        .spyOn(global.Date, 'now')
        .mockImplementationOnce(() =>
          Date.now().valueOf()
        );
      const targetResource = 'some-uuid';
      const result = await service.destroy(targetResource);
      expect(result).toBeTruthy();
      expect(userRepositoryMock.update).toHaveBeenCalledWith({ userUUID: targetResource }, { deletedDate: getNow() });
    });
  });

我曾认为.spyOn(global.Date)会模拟整个全局dat函数,但我的代码库中的Date.now()仍返回实际日期而不是模拟日期。

我的问题是,是否有一种方法可以从测试中提供在存储库中调用的Date.now的模拟返回值,还是我应该DI注入一个DateProvider到存储库类中,然后可以从我的测试中模拟它?

1个回答

4

jest.spyOn(Date, 'now') 应该可以使用。

例如:

userService.ts:

import UserRepository from './userRepository';

class UserService {
  private userRepository: UserRepository;
  constructor(userRepository: UserRepository) {
    this.userRepository = userRepository;
  }
  public async destroy(uuid: string): Promise<boolean> {
    await this.userRepository.update({ userUUID: uuid }, { deletedDate: Date.now() });
    return true;
  }
}

export default UserService;

userRepository.ts:

class UserRepository {
  public async update(where, updater) {
    return 'real update';
  }
}

export default UserRepository;

userService.test.ts:

import UserService from './userService';

describe('60204284', () => {
  describe('#UserService', () => {
    describe('#destroy', () => {
      it('should soft delete user', async () => {
        const mUserRepository = { update: jest.fn() };
        const userService = new UserService(mUserRepository);
        jest.spyOn(Date, 'now').mockReturnValueOnce(1000);
        const actual = await userService.destroy('uuid-xxx');
        expect(actual).toBeTruthy();
        expect(mUserRepository.update).toBeCalledWith({ userUUID: 'uuid-xxx' }, { deletedDate: 1000 });
      });
    });
  });
});

100%覆盖率的单元测试结果:

 PASS  stackoverflow/60204284/userService.test.ts
  60204284
    #UserService
      #destroy
        ✓ should soft delete user (9ms)

----------------|---------|----------|---------|---------|-------------------
File            | % Stmts | % Branch | % Funcs | % Lines | Uncovered Line #s 
----------------|---------|----------|---------|---------|-------------------
All files       |     100 |      100 |     100 |     100 |                   
 userService.ts |     100 |      100 |     100 |     100 |                   
----------------|---------|----------|---------|---------|-------------------
Test Suites: 1 passed, 1 total
Tests:       1 passed, 1 total
Snapshots:   0 total
Time:        5.572s, estimated 11s

源代码:https://github.com/mrdulin/react-apollo-graphql-starter-kit/tree/master/stackoverflow/60204284

该链接为 React、Apollo 和 GraphQL 的起始套件示例代码,可供研究学习。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接