Skip to content

Obsidianプラグイン開発でobsidianに依存するコードにおいてJestを利用する

Posted on:2024年4月25日 at 22:00

目次

  1. 困ったこと
  2. 結論
  3. 参考文献
  4. obsidian側
    1. obsidian内部のmomentを利用すること
  5. Jest側
    1. mocking
    2. esModuleInteropは利用しない
  6. まとめ

困ったこと

Obsidianプラグイン開発にて、Jestを導入してルンルン開発をしていたある日のこと。 時間周りをよしなに操作できるライブラリ、Moment.js周辺のテストを書いているときに事は起こりました。

Jestによるテスト中のlocaleは任意のもの(今回はja)に設定できるのに、実際に実行するとMomentのlocaleが何をやってもenに固定されてしまうのです。

でもでも、moment.locale()を見てもしっかりjaになっている。どうして… 画像右側ではmoment.locale()がしっかりjaになっているのに対して、左下の部分ではlocaleが適用されず曜日表示が英語になっています。

結論

import { moment } from 'obsidian' を使おう!

でもそうなると今度はJestが動かなくなる。

これはobsidianのmomentに依存するため。
なのでJest部分はモックしてobsidianへの依存を回避しよう!

参考文献

obsidian側

obsidian内部のmomentを利用すること

というのもMoment.jsが提供するmomentとObsidian APIが提供するmomentは完全に別物っぽいです。

このため、Obsidian内部のmomentを利用しないとlocaleが正しく動作せず、つねにenとなってしまいます。

Jest側

Jestが提供しているモック機能を利用してobsidianmomentを手元でMoment.jsmomentに切り替えてしまいましょう。

今回はmoment.Date()のMockingを行います。

mocking

後述しますが、import moment from 'moment'ではなく、import * as moment from 'moment'とするのがミソです。

import * as moment from "moment";

jest.mock(
  "obsidian",
  () => ({
    moment: (date: Date) => {
      moment.locale("ja");
      return moment(date);
    },
  }),
  { virtual: true }
);

esModuleInteropは利用しない

先ほど言及した話題ですが、 import moment from 'moment' を使おうとするとesModuleInteropを有効にすることが要求されます。 しかし、要求の通りesModuleInteropを有効にするとobsidian側のmomentで赤線が引かれてうざったいです。

これはimport * as moment from 'moment' と宣言することで回避できます。

まとめ

とりあえず貼ったコードを実行するとうまく動いたのでまとめました。

需要があるかは分かりません。