테스트/단위 테스트 (Vue)
단위 테스트 - Movie 스토어
IT Blue
2021. 9. 10. 02:37
단위 테스트 - Movie 스토어
Movie.js
/* 영화 검색과 관련된 데이터를 취급하는 용도 */
import axios from 'axios'
import _uniqBy from 'lodash/uniqBy'
const _defaultMessage = 'Search for the movie title!'
export default {
namespaced: true,
state: () => ({
movies: [],
message: _defaultMessage,
loading: false,
theMovie: {}
}),
getters: {},
mutations: {
updateState(state, payload) {
Object.keys(payload).forEach(key => {
state[key] = payload[key]
})
},
resetMovies(state) {
state.movies = []
state.message = _defaultMessage
state.loading = false
}
},
// 비동기
actions: {
async searchMovies({ state, commit }, payload) {
if (state.loading) return
commit('updateState', {
message: '',
loading: true
})
try {
const res = await _fetchMovie({
...payload,
page: 1
})
const { Search, totalResults } = res.data
commit('updateState', {
movies: _uniqBy(Search, 'imdbID')
})
console.log(totalResults) // 266
console.log(typeof totalResults) // string
const total = parseInt(totalResults, 10)
const pageLength = Math.ceil(total / 10)
// 추가 요청
if (pageLength > 1) {
for (let page = 2; page <= pageLength; page += 1) {
if (page > (payload.number / 10)) break
const res = await _fetchMovie({
...payload,
page
})
const { Search } = res.data
commit('updateState', {
movies: [
...state.movies,
..._uniqBy(Search, 'imdbID')]
})
}
}
} catch ({ message }) {
commit('updateState', {
movies: [],
message
})
} finally {
commit('updateState', {
loading: false
})
}
},
async searchMovieWithId({ state, commit }, payload) {
if (state.loading) return
commit('updateState', {
theMovie: {},
loading: true
})
try {
const res = await _fetchMovie(payload)
console.log(res.data)
commit('updateState', {
theMovie: res.data
})
} catch ({ message }) {
commit('updateState', {
theMovie: {},
message
})
} finally {
commit('updateState', {
loading: false
})
}
}
}
}
async function _fetchMovie(payload) {
return await axios.post('/.netlify/functions/movie', payload)
}
Movie.test.js
import movieStore from '~/store/movie'
import _cloneDeep from 'lodash/cloneDeep'
import axios from 'axios'
describe('store/movie.js', () => {
let store
beforeEach(() => {
// _cloneDeep - 깊은 복사, 객체 데이터 복사
store = _cloneDeep(movieStore)
store.state = store.state()
store.commit = (name, payload) => {
// store.actions.updateState(store.state, payload)
store.mutations[name](store.state, payload)
}
store.dispatch = (name, payload) => {
const context = {
state: store.state,
commit: store.commit,
dispatch: store.dispatch
}
// action 을 return 키워드로 반환 - 비동기
// store.actions.searchMovies(context, payload)
return store.actions[name](context, payload)
}
})
test('영화 데이터를 초기화', () => {
store.commit('updateState', {
movies: [{ imdbID: '1' }],
message: 'Hello world',
loading: true
})
store.commit('resetMovies')
expect(store.state.movies).toEqual([])
expect(store.state.message).toBe('Search for the movie title!')
expect(store.state.loading).toBe(false)
})
test('영화 목록을 잘 가져온 경우 데이터를 확인', async () => {
const res = {
data: {
totalResults: '1',
Search: [
{
imdbID: '1',
Title: 'ITBlue',
Poster: 'ITBlue.jpg',
Year: '2021'
}
]
}
}
// axios.post = jest.fn(() => {
// return new Promise(resolve => {
// resolve(res)
// })
// })
axios.post = jest.fn().mockResolvedValue(res)
await store.dispatch('searchMovies')
expect(store.state.movies).toEqual(res.data.Search)
})
test('영화 목록을 가져오지 못한 경우 에러 메시지를 확인', async () => {
const errorMessage = 'Network Error.'
axios.post = jest.fn().mockRejectedValue(new Error(errorMessage))
await store.dispatch('searchMovies')
expect(store.state.message).toBe(errorMessage)
})
test('영화 아이템이 중복된 경우 고유하게 처리', async () => {
const res = {
data: {
totalResults: '1',
Search: [
{
imdbID: '1',
Title: 'ITBlue',
Poster: 'ITBlue.jpg',
Year: '2021'
},
{
imdbID: '1',
Title: 'ITBlue',
Poster: 'ITBlue.jpg',
Year: '2021'
},
{
imdbID: '1',
Title: 'ITBlue',
Poster: 'ITBlue.jpg',
Year: '2021'
}
]
}
}
axios.post = jest.fn().mockResolvedValue(res)
await store.dispatch('searchMovies')
expect(store.state.movies.length).toBe(1)
})
test('단일 영화의 상세 정보를 잘 가져온 경우 데이터를 확인', async () => {
const res = {
data: {
imdbID: '1',
Title: 'Frozen',
Poster: 'frozen.jpg',
Year: '2021'
}
}
axios.post = jest.fn().mockResolvedValue(res)
await store.dispatch('searchMovieWithId')
expect(store.state.theMovie).toEqual(res.data)
})
})