目次
困ったこと
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への依存を回避しよう!
参考文献
- Error running tests · Issue #13 · obsidianmd/obsidian-api
- 要はJestでObsidianAPIは叩けないって話(だと思う)
- Unit test with jest · Issue #2 · songkg7/o2
- JestでObsidianAPIをMockする方法
obsidian側
obsidian内部のmomentを利用すること
というのもMoment.jsが提供するmomentとObsidian APIが提供するmomentは完全に別物っぽいです。
このため、Obsidian内部のmomentを利用しないとlocaleが正しく動作せず、つねにen
となってしまいます。
Jest側
Jestが提供しているモック機能を利用してobsidian
のmoment
を手元でMoment.js
のmoment
に切り替えてしまいましょう。
今回は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'
と宣言することで回避できます。
まとめ
とりあえず貼ったコードを実行するとうまく動いたのでまとめました。
需要があるかは分かりません。