Тестирование Nest js - сервисный метод возвращает данные, когда они не должны - PullRequest
0 голосов
/ 03 апреля 2020

Я пишу модульный тест, который высмеивает создание нового пользователя в базе данных. Внутри метода user.service.add я делаю вызов findOne, чтобы проверить, существует ли пользователь в БД. В разработке это работает правильно, однако, в тесте - findOne возвращает данные, когда они не должны.

по крайней мере, я не думаю, что это должно. Почему он возвращает данные?

мой тест

const testUserUsername1 = faker.internet.userName();
const testUserEmail1 = faker.internet.email();
const testUserPassword1 = faker.internet.password();
const testUserName1 = `${faker.name.firstName()} ${faker.name.lastName()}`;

const testUserName2 = `${faker.name.firstName()} ${faker.name.lastName()}`;

// user test object
const testUser = new User(
  testUserName1,
  testUserEmail1,
  testUserPassword1,
  testUserUsername1,
);

describe('UserService', () => {
  let userService: UserService;
  let postService: PostService;
  let likeService: LikeService;
  let userRepository: Repository<User>;

  beforeEach(async () => {
    const module: TestingModule = await Test.createTestingModule({
      providers: [
        UserService,
        {
          provide: getRepositoryToken(User),
          useClass: Repository,
        },
        {
          provide: getRepositoryToken(User),
          // mocks of all the methods from the User Service
          useValue: {
            save: jest.fn(),
            create: jest.fn().mockReturnValue(testUser),
            find: jest.fn().mockResolvedValue(testUsers),
            findOne: jest.fn().mockResolvedValue(testUser),
            update: jest.fn().mockResolvedValue(testUser),
            delete: jest.fn().mockResolvedValue(true),
          },
        },
        PostService,
        {
          provide: PostService,
          useClass: Repository,
        },
        LikeService,
        {
          provide: LikeService,
          useClass: Repository,
        },
      ],
    }).compile();
    userRepository = module.get<Repository<User>>(getRepositoryToken(User));
    userService = module.get<UserService>(UserService);
    postService = module.get<PostService>(PostService);
    likeService = module.get<LikeService>(LikeService);
  });

it('should be able to create a user', async () => {
    const tempUser = {
      name: testUserName1,
      email: testUserEmail1,
      username: testUserUsername1,
      password: testUserPassword1,
    }
    userRepository.findOne = jest.fn(() => tempUser.username);

    await userService.add(tempUser)
    expect(tempUser).toEqual(testUser);
  });
  afterEach(() => {
    jest.resetAllMocks();
  });
});

user.service.add

  async add(userDto: Partial<UserCreateDTO>): Promise<UserDTO> {
    // get data from args
    const { name, password, username, email } = userDto;

    // check if the user exists in the db
    const userInDb = await this.userRepository.findOne({
      where: { username },
    });

    console.log('username: ', username)
    console.log('userInDb: ', userInDb)

    if (userInDb) {
      throw new HttpException('User already exists', HttpStatus.BAD_REQUEST);
    }

    // create new user 
    const user: User = await this.userRepository.create({
      name,
      password,
      username,
      email,
    });

    // save changes to database
    await this.userRepository.save(user);

    // return user object
    return toUserDto(user);
  }

вывод console.log внутри user.service.add

   console.log src/user/user.service.ts:49
      username: Mayra_Rolfson53
    console.log src/user/user.service.ts:50
      userInDb: User {
        name: 'Albert Kuvalis',
        email: 'Martin_Jacobson@gmail.com',
        username: 'SQT_L6iGKzPVFPI',
        password: 'Mayra_Rolfson53'
      }

выдана ошибка

    User already exists

      50 |     console.log('userInDb', userInDb)
      51 |     if (userInDb) {
    > 52 |       throw new HttpException('User already exists', HttpStatus.BAD_REQUEST);
         |             ^
      53 |     }

1 Ответ

0 голосов
/ 03 апреля 2020

Я думаю, что решение состоит в том, чтобы добавить тип возврата, когда пользователь НЕ обнаружил в моем методе findOne

ДО

  async findOne(uid: string): Promise<User> {
    return await this.userRepository.findOne({
      relations: ['posts', 'comments'],
      where: { uid },
    });
  }

ПОСЛЕ

  async findOne(uid: string): Promise<User | undefined> {
    return await this.userRepository.findOne({
      relations: ['posts', 'comments'],
      where: { uid },
    });
  }

сейчас В моем тесте я ожидаю, что undefined будет возвращено вместо testUser в моем findOne макете

  it('should be able to create a user', async () => {
    const tempUser = {
      name: testUserName1,
      email: testUserEmail1,
      username: testUserUsername1,
      password: testUserPassword1,
    }
    userRepository.findOne = jest.fn(() => undefined);

    await userService.add(tempUser)
    expect(tempUser).toEqual(testUser);

  });

мой тест теперь проходит, однако я не знать, является ли это лучшей практикой в тестировании TypeScript или Nest. js в целом. Если у кого-то есть лучшие предложения, пожалуйста, не стесняйтесь публиковать его!

спасибо @amakhrov за подсказку в комментариях!

...