【Nuxt.js】@nuxtjs/composition-apiでuseContextから読み込んだaxiosをテストする
@nuxtjs/composition-apiを使ったプロジェクトで、$axios.post
を発火するメソッドをテストをする際にかなり詰まったので記事にします。
検証環境
- nuxt: 2.15.3
- @nuxtjs/composition-api: 0.22.3
- @nuxt/typescript-build: 2.1.0
- jest: 26.6.3
- @vue/test-utils: 1.1.3
ざっくり結論
Vue Test Utilsのマウンティングオプションで$nuxt
とcontext
をモックする
$axiosが読み込まれない問題
useContext()
から$axios
を読み込み、post
やget
を叩く実装をしている場合、テストで$axios
を読み込んでくれないことがあります。
<template> <div> <h1>axios</h1> <el-button round @click="axiosMethod">button</el-button> </div> </template> <script lang="ts"> import { defineComponent, useContext } from '@nuxtjs/composition-api' export default defineComponent({ setup() { const { $axios } = useContext() const axiosMethod = async () => { await $axios.post('api/hoge') } return { axiosMethod, } }, }) </script> <style></style>
import { shallowMount, createLocalVue } from '@vue/test-utils' import Element from 'element-ui' import AxiosPage from '@/pages/form/axios.vue' const localVue = createLocalVue() localVue.use(Element) const mockAxios = { post: jest.fn(), } describe('Axios', () => { let wrapper beforeEach(() => { wrapper = shallowMount(AxiosPage, { localVue, mocks: { $axios: mockAxios, }, }) }) describe('単体テスト', () => { describe('axiosMethod', () => { it('POST api/hogeが叩かれる', async () => { await wrapper.vm.axiosMethod() expect(mockAxios.post).toHaveBeenCalledTimes(1) }) }) }) })
● Axios › 単体テスト › axiosMethod › POST api/hogeが叩かれる TypeError: Cannot read property 'post' of undefined 14 | 15 | const axiosMethod = async () => { > 16 | await $axios.post('api/hoge') | ^ 17 | } 18 | 19 | return {
Option apiでは上記のテストで通ります(多分)。
composition apiにおけるjest
jestはNuxtのcontextを知らないので、contextから読み込む$axios
は$nuxt
としてmockしてあげる必要があるようです。
// ・・・ const mockAxios = { post: jest.fn(), } describe('Axios', () => { let wrapper beforeEach(() => { wrapper = shallowMount(AxiosPage, { localVue, mocks: { $nuxt: { // 追加 context: { // 追加 $axios: mockAxios, }, }, }, }) }) // ・・・ })
$ yarn test yarn run v1.22.10 $ jest --config jest.config.js PASS test/axios.spec.js Axios 単体テスト axiosMethod ✓ POST api/hogeが叩かれる (53 ms) Test Suites: 1 passed, 1 total Tests: 1 passed, 1 total Snapshots: 0 total Time: 4.24 s Ran all test suites. ✨ Done in 5.19s.
通りました!
ついでにcontext.rootについて
$axios
(などnuxtのcontextに依存するもの)を利用したい場合、以下のようにsetup
メソッドの第二引数からcontext
を受け取り、root
から読み込むことが推奨されている文献をよく見かけます。
<script lang="ts"> import { defineComponent } from '@nuxtjs/composition-api' export default defineComponent({ setup(_, context) { const axiosMethod = async () => { await context.root.$axios.post('api/hoge') } return { axiosMethod, } }, }) </script>
root
からの読み込みはVue3で非推奨の書き方のようです。
@nuxtjs/composition-api
では基本的にuseContext
から使うので大丈夫だと思いますが、composition api導入当初は戸惑いポイントだったので、気をつけたいと思います。