Skip to content

Commit

Permalink
test: fix user.service tests cortip#108
Browse files Browse the repository at this point in the history
  • Loading branch information
naftalimurgor committed Dec 6, 2023
1 parent d223029 commit 26355dd
Showing 1 changed file with 79 additions and 40 deletions.
119 changes: 79 additions & 40 deletions apps/api/src/user/user.service.spec.ts
Original file line number Diff line number Diff line change
@@ -1,101 +1,140 @@
import { Test, type TestingModule } from '@nestjs/testing'
import { getRepositoryToken } from '@nestjs/typeorm'
import { createMock } from 'ts-auto-mock'
import type { Repository } from 'typeorm'

import type { UserUpdate } from './dto/user-update.dto'
import { UserService } from './user.service'
import { UserEntity } from '../entities/user.entity'
import { NotFoundException } from '@nestjs/common'

type MockType<T> = {
[P in keyof T]?: jest.Mock<{}>
}

describe('UserService', () => {
let service: UserService
let mockedUserRepository: jest.Mocked<Repository<UserEntity>>
let userService: UserService
let mockedUserRepository: MockType<Repository<UserEntity>>

const testUser = {
id: 1,
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
password: 'Pa$$w0rd'
}

const userRepositoryMockFactory: () => MockType<Repository<any>> = jest.fn(
() => ({
create: jest.fn(entity => entity),
findOne: jest.fn(({ where }) => testUser),
update: jest.fn(),
save: jest.fn().mockImplementationOnce((entity) => {
return Promise.resolve(testUser)
}),
findOneBy: jest.fn(),
merge: jest.fn(),
})
)


beforeEach(async () => {
const module: TestingModule = await Test.createTestingModule({
providers: [UserService]
})
.useMocker(token => {
if (Object.is(token, getRepositoryToken(UserEntity))) {
return createMock<Repository<UserEntity>>()
providers: [
UserService,
{
provide: getRepositoryToken(UserEntity),
useFactory: userRepositoryMockFactory
}
})
.compile()
]
}).compile()

service = module.get<UserService>(UserService)
userService = module.get<UserService>(UserService)
mockedUserRepository = module.get(getRepositoryToken(UserEntity))
})

afterEach(() => {
jest.clearAllMocks()
})

it('should be an instanceof UserService', () => {
expect(service).toBeInstanceOf(UserService)
expect(userService).toBeInstanceOf(UserService)
})

it('should create a new user', async () => {
const data = {
firstName: 'John',
lastName: 'Doe',
email: '[email protected]',
password: 'Pa$$w0rd'
}

mockedUserRepository.save.mockResolvedValueOnce(
createMock<UserEntity>(data)
)
const user = await service.create(data)
mockedUserRepository.create.mockReturnValueOnce(testUser)
const user = await userService.create(testUser)

expect(user).toBeDefined()
expect(user.id).toEqual(testUser.id)
})

it('should find one user', async () => {
const email = '[email protected]'

mockedUserRepository.findOne.mockResolvedValueOnce(
createMock<UserEntity>({ email })
)
const user = await service.findOne({ where: { email } })
mockedUserRepository.findOne.mockImplementation(() => {
return Promise.resolve(testUser)
})

const user = await userService.findOne({ where: { email } })

expect(user).toBeDefined()
expect(user).toHaveProperty('email', '[email protected]')
expect(mockedUserRepository.findOne).toHaveBeenCalledTimes(1)
})

it('should throw on find one when the user not exist', async () => {
mockedUserRepository.findOne.mockResolvedValueOnce(undefined)
mockedUserRepository.findOne.mockImplementationOnce(({ where }) => {
return Promise.reject(
new NotFoundException("\"There isn't any user with identifier: [object Object]\""))
})

await expect(
service.findOne({ where: { email: '[email protected]' } })
).rejects.toThrowErrorMatchingInlineSnapshot(
userService.findOne({ where: { email: '[email protected]' } })
).rejects.toThrow(
`"There isn't any user with identifier: [object Object]"`
)
})

it('should update an user', async () => {
const id = 1
const updates: UserUpdate = {
firstName: 'Jhonny',
firstName: 'John',
lastName: 'Doe'
}

mockedUserRepository.save.mockResolvedValueOnce(
createMock<UserEntity>(updates)
)
const user = await service.update(id, updates)
mockedUserRepository.findOneBy.mockImplementation(({ id }) => {
return Promise.resolve(testUser)
})

jest.spyOn(mockedUserRepository, 'merge').mockImplementationOnce((user, updates) => {
return Promise.resolve({ testUser, ...updates })
})

const user = await userService.update(id, updates)

expect(user).toBeDefined()
expect(user).toHaveProperty('firstName', updates.firstName)
expect(mockedUserRepository.merge).toHaveBeenCalled()
expect(mockedUserRepository.merge).toHaveBeenCalledTimes(1)

})

it('should throw on update when the user not exist', async () => {
const id = 0
const id = 1
const updates: UserUpdate = {
firstName: 'Jhonny',
lastName: 'Doe'
}
mockedUserRepository.findOneBy.mockResolvedValueOnce(undefined)

mockedUserRepository.findOneBy.mockImplementationOnce(({ id }) => {
return Promise.reject(new NotFoundException(`There isn't any user with id: ${id}`))
})

await expect(
service.update(id, updates)
userService.update(id, updates)
).rejects.toThrowErrorMatchingInlineSnapshot(
`"There isn't any user with id: 0"`
`"There isn't any user with id: 1"`
)
expect(mockedUserRepository.findOneBy).toHaveBeenCalledWith({ id })
expect(mockedUserRepository.findOneBy).toHaveBeenCalledTimes(1)
})
})

0 comments on commit 26355dd

Please sign in to comment.