質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

91.05%

  • JavaScript

    13324questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Vue.js

    370questions

    Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

  • Electron

    167questions

    Electronは、HTML5とNode.jsというWebの技術を用いてデスクトップアプリケーションを作成できるクロスプラットフォームな実行環境です。

Vue.js で methods のユニットテストを行いたい

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 2
  • VIEW 330

1ntegrale9

score 24

前提・実現したいこと

Vueコンポーネント内のmethodsのユニットテストを行おうとしています。

electron-vue というボイラープレートを使用したアプリケーションを構築しています。
Karma, Chai, Mochaによって自動テストを実行しています。

発生している問題・エラーメッセージ

自動テストを実行すると、

  Target.vue
    ✗ methods unit test
    TypeError: _Target2.default.test is not a function
        at Context.it (webpack:///test/unit/specs/Target.spec.js:9:18 <- index.js:22935:29)

というエラーメッセージが発生します。
レンダリングと参照は問題なさそうなのですが、
test()が関数ではないと言われており、その原因が分かりません。

該当のソースコード

テストしたいVueコンポーネント(Target.vue)とメソッド(test)

<script>
  export default {
    methods: {
      test () {
        return 'test'
      },
    }
  }
</script>

テストコード(Target.spec.js)

import Vue from 'vue'
import Target from '@/components/Target'

describe('Upload.vue', () => {
  it('methods unit test', () => {
    const vm = new Vue(Target).$mount()
    expect(vm.test()).toBe('test')
  })
})

試したこと

Vue.jsのユニットテストとして紹介されているような、
以下のサンプルは問題なくテストをパスします。

import Vue from 'vue'
import Target from '@/components/Target'

describe('Target.vue', () => {
  it('should render correct contents', () => {
    const vm = new Vue({
      el: document.createElement('div'),
      render: h => h(Target)
    }).$mount()

    expect(vm.$el.querySelector('.title').textContent).to.contain('sample text')
  })
})

指定の方法がおかしいのかと思い、以下のパターンを試しました。

vm.test()ではなくvm.methods.test()としてみるパターン

expect(vm.methods.test()).toBe('test')

vm.test()ではなくvm.default.test()としてみるパターン

expect(vm.default.test()).toBe('test')

new Vueせず直接Target.test()としてみるパターン

expect(Target.test()).toBe('test')

また、以下の記事を参考にして試行錯誤を行いました。

ユニットテスト · electron-vue
単体テスト — Vue.js
モックを使用したテスト · vue-loader
Vue.js Vueコンポーネントのユニットテストを書いてみよう - Qiita
Vueコンポーネントのユニットテスト - SSSSLIDE
Vue.js の 単体テストについて、webpackなどビルドツールがない状況での環境を構築する - Qiita
vue-test-utilsでvuexモジュールのテストを書く - Qiita
Vuexの状態を包括的にテストする - Qiita

補足情報(言語/FW/ツール等のバージョンなど)

ライブラリ等は全て最新のものを使用しています。

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 2

check解決した方法

0

以下の点に留意することで無事にテストが通りました。

vm.methods.test()でもなくvm.default.test()でもなく
vm.test()を指定するのが正解でした。  

toBe()という関数は対応しておらず、
equals()という関数を使用する必要がありました。

結果的に以下のコードでテストを通りました。

import Vue from 'vue'
import Target from '@/components/Target'

describe('Upload.vue', () => {
  it('methods unit test', () => {
    const vm = new Vue(Target).$mount()
    expect(vm.test()).equals('test')
  })
})

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

0

    const vm = new Vue(Target).$mount()


ではなくサンプルの通り

    const vm = new Vue({
      el: document.createElement('div'),
      render: h => h(Target)
    }).$mount()


とすればいいのではないでしょうか。

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/01/09 10:09 編集

    回答ありがとうございます。
    そのように変更したところ、

    expect(vm.test()).toBe('test')

    という指定で

    Target.vue
    ✗ methods unit test
    TypeError: vm.test is not a function
    at Context.it (webpack:///test/unit/specs/Target.spec.js:11:14 <- index.js:22937:15)

    というエラーメッセージとなりました。

    expect(vm.default.test()).toBe('test')

    という指定の場合、

    Upload.vue
    ✗ methods unit test
    TypeError: Cannot read property 'test' of undefined
    at Context.it (webpack:///test/unit/specs/Upload.spec.js:11:22 <- index.js:22937:22)

    というようにundefinedとなるので、
    レンダリング自体はそちらの方法でも、元の方法でも問題ないようです。

    キャンセル

  • 2018/01/09 15:01

    vm.default とはなんでしょうか?
    https://vuejs.org/v2/api/#methods
    「Methods to be mixed into the Vue instance. You can access these methods directly on the VM instance」とあるので、method は vue instance の直接のプロパティとして呼び出せるはずです。

    Target のインポートは正しく出来ていますでしょうか?

    キャンセル

  • 2018/01/09 15:12

    vm.default は、export default の仕様を完全に理解していないために試したもので、
    間違った指定であり、vm.test() の指定が正しいことを示すものです。

    「試したこと」に示してあるサンプルのテストをパスすることから、
    Target のインポートは正しくできていると思われます。

    キャンセル

  • 2018/01/09 15:32

    質問文にある Target.vue の script は } が1つ足りないですが、それは原因ではないですか?

    キャンセル

  • 2018/01/09 15:35

    やっぱり私の回答のやり方では無理ですね(vm が Target のインスタンスではないので)。すみません。

    キャンセル

  • 2018/01/09 15:40

    失礼しました、質問用に色々削った際に余計に削っていました。(修正しました)
    元々は存在し、ESLintもエラーを出していないので、それは原因ではないです。

    ありがとうございます、他にも色々と模索してみます。

    キャンセル

15分調べてもわからないことは、teratailで質問しよう!

  • ただいまの回答率 91.05%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    javascriptの非同期処理、promiseについて

    概要 現在、javascriptとelectronを用いて、メモ帳アプリのようなものを作っています。 データベースへのアクセスに伴う非同期処理について、promiseの使い方が

  • 解決済

    【JavaScript】indexOfで特定文字が反応しない

    JavaScriptのindexOfメソッドで、文章の検索を実行しているのですが、 何故か「よという文字だけが反応しません。 「あや「漢、「alphaなどはしっかりと開始位

  • 解決済

    Electron ウィンドウの手前・奥 移動

    Electronでデスクトップウィジェットを作っています。 JavaScriptから、ウィンドウを最前面や最背面に移動する方法を教えてください。

  • 解決済

    javascriptでキーボードからの入力を変数に代入する方法

    Javascript初心者です。 初歩的な質問かもしれませんが、検索してもヒットしなかったため、質問します。 javascriptで、キーボードから入力された値を変数に代入

  • 受付中

    Electronが実行できない

    前提・実現したいこと Electronを使用してアプリケーションを作成しています 発生している問題・エラーメッセージ main\.js:9 app\.on\('windo

  • 解決済

    electron getElementsByClassNameにアクセス

    electronでmysqlのデータをtableタグに一覧を表示するアプリを作成しています。 tableタグに表示したIDをクリックしてそのIDに関する情報を別のウインドウに表示

  • 解決済

    electronパッケージ化でエラー

    前提・実現したいこと electronパッケージ化でエラーが発生しました。 どうすれば良いでしょうか。 発生している問題・エラーメッセージ $ sudo electron-pa

  • 解決済

    Reactコンポーネント外からSetState()を実行したい

    前提・実現したいこと electron + Reactで開発を行っています。 プログラミングに関しては初級者レベルのため、説明不足な部分や、意味が伝わらない部分があるかもしれません

同じタグがついた質問を見る

  • JavaScript

    13324questions

    JavaScriptは、プログラミング言語のひとつです。ネットスケープコミュニケーションズで開発されました。 開発当初はLiveScriptと呼ばれていましたが、業務提携していたサン・マイクロシステムズが開発したJavaが脚光を浴びていたことから、JavaScriptと改名されました。 動きのあるWebページを作ることを目的に開発されたもので、主要なWebブラウザのほとんどに搭載されています。

  • Vue.js

    370questions

    Vue.jsは、Webアプリケーションのインターフェースを構築するためのオープンソースJavaScriptフレームワークです。

  • Electron

    167questions

    Electronは、HTML5とNode.jsというWebの技術を用いてデスクトップアプリケーションを作成できるクロスプラットフォームな実行環境です。