DOMに依存するユニットテストを行っていると、navigator.userAgentに応じて処理を変えているような実装をテストしたいことがある。navigator.userAgentに応じて処理を変えている例としては、特定のブラウザで動かない機能のUIをそのブラウザでは隠すなどといったものがある。そのようなテストをしたい場合、テスト時のみ一時的にnavigator.userAgentを書き換え、そのテストが終わったら元に戻すということをして、挙動をユニットテストしたい。navigator.userAgentを一時的にモックしたい。利用のイメージとしては次のコードのとおり。stubUserAgent関数を呼ぶと一時的にnavigator.userAgentを書き換え、この関数から返ってきたオブジェクトのrestoreメソッドを呼ぶことで元に戻すということをしている。defaultUserAgent);});stubUserAgentを実装する上で紹介したようなnavigator.userAgentを一時的にモックすることを実現するために、stubUserAgent関数を実装してみた。jsdomの環境下ではおそらく動くと思う。userAgentが定義されているはず。定義したuserAgentプロパティをdeleteすれば戻せる。};}手順としては、もともとの状態を取っておき、deinePropertyを使ってnavigator.userAgentを再定義し、restoreを呼んだ時に元に戻すというだけである。navigatorのオブジェクト自体にuserAgentプロパティがある場合と、prototypeの方でuserAgentが定義されている場合の二通りがあるため、少し複雑化している。definePropertyで定義しなければいけないかちなみに単純に考えると以下のようにすればうまくいくのでは?と思えてしまう。この方法だとnavigator.userAgentへの代入が出来ないためにうまくいかない。};}JSではプロパティにもいろんなメタ情報があって、そのメタ情報を設定することで以下のような項目などを制御できる。navigator.userAgentはgetterとして定義されていて、またwritableはfalseとして定義されているため、プロパティへの値の代入は出来ない状態になっている。configurableという属性はtrueとなっているため、definePropertyという関数を使えば再定義することは可能となっている。これらの理由から、一時的に書き換えければdefinePropertyを使うしか方法がなかった。configurableさえfalseになっていると、そもそも値の書き換えを行うことはできなくなってしまう。このため、navigator.userAgentプロパティのconfigurableをfalseとしているSafariにおいては、上のような実装すらも動かない。なってくると、userAgentを判定するようなクラスを作り、そのクラスのメソッドをモックするという方法を使うしかないだろう。まとめ今回はnavigator.userAgentの値を一時的に書き換えてテストする方法について書いてみた。いう方法で良いのか不安なので、よりクールな方法があれば教えてほしいです。WORKSHOPをやったNext.jsのドキュメントを全部読んでみた最近連載開始して3巻程度で好きな作品たち月別アーカイブはてなブログをはじめよう!shiba_yu36さんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。