ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 단위 테스트 - Movie 스토어
    테스트/단위 테스트 (Vue) 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)
      })
    })

    댓글

Designed by Tistory.