スマレジエンジニアyushiのブログ

スマレジエンジニアのブログ

【将棋盤 第12回】vueのテストコードを記述してみる

コツコツ将棋盤を作ってます。

使用技術

  • Vue.js3
  • Vite
  • SCSS

yushi-dev.hatenablog.com

公開ページ

https://nek0meshi.github.io/shogi-board/

今回は、vueファイルのテストコードを書いてみます。

vite2へのmigration

vite2がリリースしていたので、こちらにアップデートしておきます。

下記の公式ドキュメントを参考にします。

Migration from v1 | Vite

yarn add -D vite

vite.config.jsだけ更新が必要なようでした。

// vite.config.js
import vue from '@vitejs/plugin-vue'

export default ({ command, mode }) => ({
  plugins: [vue()],
  base: command === 'serve' ? '/' : '/shogi-board/',
})

ライブラリの導入

下記のドキュメントを参考にしながら進めていきます。

Using with TypeScript | Vue Test Utils

Add testing to Vite - DEV Community

yarn add -D vue-jest @vue/test-utils @types/jest@^26.0.24 ts-jest@^26.5.6 typescript vue-jest

ここで、@types/jestとts-jestは、jestとメジャーバージョンが同じものを指定する必要があることに、注意が必要です。今回は、26系の最新を指定します。

対象のVueファイルの用意

既存のソースの一部の機能を、Vueコンポーネントとして切り出します。

<template>
  <div
    class="piece"
    :style="pieceStyle"
    :class="pieceClass"
    @click="clickPiece"
  >
    {{ piece.name }}
  </div>
</template>

<script lang="ts">
import { computed, defineComponent, PropType } from 'vue'
import { Piece } from '../src/pieces'
export default defineComponent({
  name: 'PieceOnBoard',
  props: {
    piece: {
      type: Object as PropType<Piece>,
    },
    isLastMoved: {
      type: Boolean,
      default: false,
    },
    isSelected: {
      type: Boolean,
      default: false,
    },
  },
  setup(props, context) {
    return {
      pieceStyle: computed(() => ({
        right: (21 + 51 * (props.piece.column - 1)) + 'px',
        top: (21 + 51 * (props.piece.row - 1)) + 'px',
        transform: 'rotate(' + (props.piece.isFirst ? 0 : 180) + 'deg)',
      })),
      pieceClass: computed(() => ({
        'selected-piece': props.isSelected,
        'last-moved-piece': props.isLastMoved,
        'promoted-piece': props.piece.isPromoted,
      })),
      clickPiece: () => {
        context.emit('clickPiece', props.piece.id)
      },
    }
  },
})
</script>

<style scoped>
  .piece {
    position: absolute;
    width: 50px;
    height: 50px;
    font-size: 32px;
    cursor: pointer;
  }
</style>

テストコードを記述

import { mount } from '@vue/test-utils'
import { Piece } from '../src/pieces'
import PieceOnBoard from './PieceOnBoard.vue'

describe('PieceOnBoard.vue', () => {
  it('駒の名前表示', () => {
    const component = mount(PieceOnBoard as any, {
      propsData: {
        piece: new Piece('pawn', true, 1, 1),
        isLastMoved: false,
        isSelected: false,
      }
    })

    const div = component.find('div')

    expect(div.text()).toBe('歩')
  })
})

テストコードを実行してみます

yarn test

yarn run v1.22.10
warning package.json: No license field
$ jest
 PASS  src/components/PieceOnBoard.spec.ts
 PASS  tests/index.test.js

Test Suites: 2 passed, 2 total
Tests:       3 passed, 3 total
Snapshots:   0 total
Time:        0.552 s, estimated 1 s
Ran all test suites.
✨  Done in 1.00s.

Pull Request

https://github.com/nek0meshi/shogi-board/pull/21

https://github.com/nek0meshi/shogi-board/pull/22

まとめ

jestにもtypescriptにもviteにも慣れていないのでかなり詰まりましたが、
なんとか完成できました。