Jest 単体テストで Vuex ストアのクローンを作成しようとすると、「TypeError: シンボル値を文字列に変換できません」というメッセージが表示されるのはなぜですか?
P粉604848588
2023-08-26 16:06:50
<p>動作する Vue 2.6 / Vuex 3.6 / TypeScript アプリケーションがあります。複雑なリファクタリングを行う前に、単体テストを追加したいと思います。 Jest と Vue Test Utils をインストールして構成したら、公式の Vue Test Utils ガイドに記載されている手順に従ってみました。 </p>
<p>この手順を私の特定のプロジェクトに合わせて変更します。</p>
<pre class="brush:js;toolbar:false;">import { createLocalVue } from '@vue/test-utils'
「vue」から Vuex をインポート
「ストア」からストアをインポートします
「lodash」から { cloneDeep } をインポートします
test("SET_CURRENT_VTK_INDEX_SLICES は VTK インデックス スライスを更新する必要があります", () => {
const localVue = createLocalVue()
localVue.use(Vuex)
const store = new Vuex.Store(cloneDeep(storeConfig))
Expect(store.state.iIndexSlice).toBe(0)
store.commit('SET_CURRENT_VTK_INDEX_SLICES', {indexAxis: 'i', value: 1 })
})
</pre>
<p>しかし、<code>npm run test:unit</code> を実行すると、次のエラーが発生します。
<ブロック引用>
<p>「TypeError: シンボル値を文字列に変換できません」</p>
</blockquote>
<p>ストアにはシンボルがないと思いますが、再帰関数を使用してストアとそのすべての子を確認します。 (このコードを覚えていない場所から盗みました): </p>
<pre class="brush:js;toolbar:false;">function findSymbolInStore(store) {
for (ストア内のconstキー) {
コンソール.ログ(キー);
if (store.hasOwnProperty(key)) {
const 値 = ストア[キー];
if (値の型 === 'オブジェクト') {
if (シンボルの値インスタンス) {
console.log(`見つかったシンボル: ${key}`);
} それ以外 {
findSymbolInStore(値);
}
}
}
}
}
findSymbolInStore(store.state);
</pre>
<p>ストアにシンボルが見つかりません。</p>
<p>さらにいくつか行き止まりに行き当たり、シンボルがどこにあるかを確認するためにストアを文字列化してみました。 </p>
<pre class="brush:js;toolbar:false;">試してください {
const thisStore = JSON.stringify(ストア);
} キャッチ (エラー) {
console.error('オブジェクトを文字列に変換中にエラーが発生しました;', err);
}
</pre>
<p>しかし、これによりエラーがスローされます: </p>
<ブロック引用>
<p>型エラー: ループ構造を JSON に変換中</p>
</blockquote>
<p>次に、<code> flatted</code> で文字列化してみます。 </p>
<pre class="brush:js;toolbar:false;">フラット化されたものを 'フラット化' からインポートします。
const stringifyStore = flatted.stringify(store);
const parsedStore = flatted.parse(stringifyStore);
</pre>
<p>これでさらに一歩前進したように見えましたが、今度はエラーが発生します: </p>
<ブロック引用>
<p>TypeError: 未定義のプロパティを読み取ることができません (「iIndexSlice」を読み取ります)</p>
</blockquote>
<p>ストア内の <code>iIndexStore</code> のデフォルト値が 0 であることがわかるため、これは奇妙です。ありがたいことに、この時点で Amit Patel が、<code>iIndexSlice</code> が未定義であるだけでなく、<code>store.state</code> 全体も未定義であることを指摘して、私を正しい軌道に乗せてくれました。 </p>
<p>私が遭遇したものと同様のエラーを含む [Vuex GitHub の問題][4] に遭遇しました。</p>
<ブロック引用>
<p>[vuex] getters は関数である必要がありますが、'getters.currentView' は {}</p> です。
</blockquote>
<p>上記の質問では、作成者はストアをエクスポートせず、ストアの構成のみをエクスポートすることを推奨しています。アプリのストアが実際のストア インスタンスをエクスポートしていることに気付きました。 Vuex ストレージ定義は次のようになります: </p>
<pre class="brush:js;toolbar:false;">const store = new Vuex.Store({
州: {
iIndexSlice: 0、
// ...
}、
ゲッター: {
currentView(状態) {
// 関数コード ...
}
突然変異: {
// コード
}、
行動: {
// コード
}
});
デフォルトストアをエクスポートします。
</pre>
<p>しかし、今はどうでしょうか? </p>
<p>HT: シンボリック デバッグを手伝ってくれた Mujeeb へ。 </p>
<p> 注: 行き止まりなどをスキップすることもできましたが、他の人も同じ困難を抱えている可能性があり、バグなどが言及されていれば答えをグーグルで検索する方が簡単かもしれないと思いました。 </p>
(「デイブはこれを修正するのにあまりにも多くの時間を費やしました...非常に些細なことですが、できれば同じ間違いを犯すであろう他の人を救うことを願っています」の別のエピソードへようこそ:
Vuex ストアを次のようにリファクタリングしました:
リーリーそれから、Jest テストに少し調整を加えるだけです:
リーリーこれで、テストは問題なく実行されます。