반응형
store -> movie.js 파일 테스트
관련 공식문서
https://jestjs.io/docs/mock-function-api
테스트를 진행할 코드
import axios from 'axios'
// 중복제거을 위해서 uniqBy를 사용
import _uniqBy from 'lodash/uniqBy'
const _defaultMessage = 'Search for the movie title!'
export default {
// module!
namespaced: true,
//data!
state: () => ({
movies: [],
message: _defaultMessage,
loading: false,
theMovie: {}
}),
// computed!
getters: {
// 실제 데이터를 계산해서 새로운 데이터 형식으로 반영할때 사용
},
// methods!
// 변이: 관리하는 데이터를 변경시켜줄수 있다. 다른 메소드에서 변경할 수 없다.
mutations: {
// ['movies', 'message', 'loading']
updateState(state, payload) {
Object.keys(payload).forEach(key => {
state[key] = payload[key]
})
},
// assignMovies (state, Search){
// state.movies = Search
// },
// 화면 이동시 초기화 설정
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
// 검색된 imdbID 데이터의 중복을 제거
// movies: _uniqBy(Search,'imdbID')
// message: 'Hello world',
// loading: true
})
try {
// const { title, type, number, year } = payload
// const OMDB_API_KEY = '7035c60c'
// http -> https 로 변경
//const res = await axios.get(`https://www.omdbapi.com/?apikey=${OMDB_API_KEY}&s=${title}&type=${type}&y=${year}&page=1`);
const res = await _fetchMovie({
// 전개연산자 사용
...payload,
page: 1
})
console.log(res);
const { Search, totalResults } = res.data
commit('updateState', {
// 검색된 imdbID 데이터의 중복을 제거
movies: _uniqBy(Search,'imdbID')
// message: 'Hello world',
// loading: true
})
console.log(totalResults) // 261
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 axios.get(`https://www.omdbapi.com/?apikey=${OMDB_API_KEY}&s=${title}&type=${type}&y=${year}&page=${page}`);
const res = await _fetchMovie({
...payload,
page: page
})
const {Search} = res.data
commit('updateState', {
// _uniqBy 를 이용해서 중복 제거
movies: [
...state.movies,
..._uniqBy(Search, 'imdbID')
]
})
}
}
} catch ({message}) {
commit('updateState', {
// 초기화
movies: [],
// 메세지 출력
message: message
})
} finally {
commit('updateState', {
loading: false
})
}
},
async searchMovieWithId({state, commit}, payload) {
if(state.loading) return
commit('updateState', {
theMovie: {},
loading: true
})
//const {id} = payload
try {
const res = await _fetchMovie(payload)
commit('updateState',{
theMovie: res.data
// id: id
})
console.log(res)
} catch(error) {
commit('updateState', {
theMovie: {}
})
} finally {
commit('updateState', {
loading: false
})
}
}
}
}
async function _fetchMovie(payload) {
// 서버리스 함수로 처리
return await axios.post('/.netlify/functions/movie', payload)
// const { title, type, year, page, id } = payload;
// const OMDB_API_KEY = '7035c60c';
// const url = id
// ? `https://www.omdbapi.com/?apikey=${OMDB_API_KEY}&i=${id}`
// : `https://www.omdbapi.com/?apikey=${OMDB_API_KEY}&s=${title}&type=${type}&y=${year}&page=${page}`;
// // const url = `https://www.omdbapi.com/?apikey=${OMDB_API_KEY}`;
// return new Promise((resolve, reject) => {
// axios.get(url)
// .then((res) => {
// // console.log(res)
// if (res.data.Error) {
// reject(res.data.Error)
// }
// resolve(res)
// })
// .catch((err) => {
// reject(err.message)
// })
// })
}
테스트 코드
import movieStore from '~/store/movie.js'
import _cloneDeep from 'lodash/cloneDeep'
import axios from 'axios'
describe('store/movie.js', () => {
let store
beforeEach(() => {
// 원본 훼손을 방지하기 위해 복사 기능 이용
store = _cloneDeep(movieStore)
store.state = store.state()
// this.$store.state.movies
store.commit = (name, payload) => {
store.mutations[name](store.state, payload)
}
store.dispatch = (name, payload) => {
const context = {
state: store.state,
commit: store.commit,
dispatch: store.dispatch
}
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)
//store.mutations.updateState(store.state, {})
//store.dispatch('searchMovies', {})
})
test('영화 목록을 잘 가져온 경우 데이터를 확인합니다.', async () => {
const res = {
data: {
totalResults: '1',
Search: [
{
imdbID: '1',
Title: 'Hello',
Poster: 'hello.jpg',
Year: '2021'
}
]
}
}
// 모의함수 및 가짜 데이터 설정
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: 'Hello',
Poster: 'hello.jpg',
Year: '2021'
},
{
imdbID: '1',
Title: 'Hello',
Poster: 'hello.jpg',
Year: '2021'
},
{
imdbID: '1',
Title: 'Hello',
Poster: 'hello.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)
})
})
반응형
'프론트엔드 > 단위 테스트' 카테고리의 다른 글
jest를 이용한 테스트시 콘솔에 내용을 호출하지 않도록 설정 (0) | 2022.02.01 |
---|---|
Movie 컴포넌트 테스트 (0) | 2022.02.01 |
Search 컴포넌트 테스트 (0) | 2022.01.31 |
Header 컴포넌트 테스트, url 테스트 (0) | 2022.01.27 |
mount vs shallowMount (0) | 2022.01.24 |