正直これで良いのかわからないけど、とりえあえず手元の clientWidth
の値を使う処理の試験は走るようになった。
メソッド系
しれっとstub的な関数で上書きする。
const { JSDOM } = require('jsdom'); const dom = new JSDOM(); const el = dom.window.document.createElement('div'); console.log(el.getBoundingClientRect()); // => { width: 0, top: 0, ... } // こうする el.getBoundingClientRect = () => ({ width: 200, }); console.log(el.getBoundingClientRect()); // => { width: 200 }
試験を通すだけなので不要な値まで全部書く必要はない。
本当なら sinon.stub()
↓の方が丁寧な感じがするけど、まあ使い捨てるインスタンスだし、良いでしょ。
sinon.stub(el, 'getBoundingClientRect").returns({ width: 200 });
プロパティ系
clientWidth
や clientHeight
は単純に代入してもだめなので、 Object.defineProerty()
で上書きする。
const { JSDOM } = require("jsdom"); const dom = new JSDOM(); const el = dom.window.document.createElement("div"); console.log(el.clientWidth); // => 0 // こうする Object.defineProperty(el, 'clientWidth', { value: 100 }); console.log(el.clientWidth); // => 100
JSDomはレイアウト計算をサポートしない
とREADMEにあるので、バグじゃないです。
Beyond just features that we haven’t gotten to yet, there are two major features that are currently outside the scope of jsdom. These are:
- Navigation: the ability to change the global object, and all other objects, when clicking a link or assigning
location.href
or similar.- Layout: the ability to calculate where elements will be visually laid out as a result of CSS, which impacts methods like
getBoundingClientRects()
or properties likeoffsetTop
.
まだやっていないだけの機能もありますが、今のところjsdomのスコープ外である主要な機能が2つあります。
- ナビゲーション: リンクをクリックしたり
location.href
を設定する等した際に、 グローバルオブジェクト他を変更する機能 - レイアウト: CSSの結果として要素が視覚的に配置された結果を計算する機能。
getBoundingClientRects()
のようなメソッドや、offsetTop
といったプロパティへ影響するもの
その他
ちなみに本物のDOMでも視覚的に配置されるまで、例えば document.body.appendChild(el)
とかするまでは値が 0
だったりします。