Jest: Object.definePropertyを䜿甚しおwindow.locationを倉曎できたせん

䜜成日 2017幎12月19日  Â·  78コメント  Â·  ゜ヌス: facebook/jest

_feature_をリク゚ストしたすか、それずも_bug_を報告したすか バグを報告

珟圚の動䜜は䜕ですか

テストスむヌト内から以䞋を呌び出したす。

Object.defineProperty(location, "hostname", {
  value: "example.com",
  writable: true
});

次の゚ラヌをスロヌしたす。

    TypeError: Cannot redefine property: hostname
        at Function.defineProperty (<anonymous>)

期埅される動䜜は䜕ですか

コヌドは䟋倖をスロヌしおはならず、 window.location.hostname === "example.com"はtrueず評䟡されるべきです。

芋た目から、 jsdomはwindow.locationを停造䞍可胜に蚭定するようになりたした。 window.location内の倀を倉曎する唯䞀の方法は、 reconfigureを䜿甚するこずですが、2460ごずにJestはテスト甚にjsdomを公​​開したせん。

正確なJest構成を提䟛し、Jest、ノヌド、ダヌン/ npmバヌゞョンずオペレヌティングシステム。

ゞェストバヌゞョン22.0.1
ノヌドバヌゞョン8.6.0
糞バヌゞョン1.2.0
OS macOS High Sierra 10.13.2

Discussion Wontfix

最も参考になるコメント

私はnpmにjest-environment-jsdom-globalずいう新しいパッケヌゞを公開したした。これは、䞀郚の人々がObject.defineProperty抱えおいる問題に圹立぀可胜性がありたす。

党おのコメント78件

同様の問題がありたす。 このように、独自のJSDOMEnvironmentを䜜成し、jsdomオブゞェクトをグロヌバルに公開できたす。

const JSDOMEnvironment = require('jest-environment-jsdom');

module.exports = class CustomizedJSDomEnvironment extends JSDOMEnvironment {
  constructor(config) {
    super(config);
    this.global.jsdom = this.dom;
  }

  teardown() {
    this.global.jsdom = null;
    return super.teardown();
  }
};

そしお、必芁に応じおテストケヌスでjsdom.reconfigureを呌び出すこずができたす

共有しおくれおありがずう、それは良い回避策です

玄束なのでsuper.teardown();を返す必芁がありたす

パヌフェクト、 @ oliverzy-詊しおみたす。 ありがずう

これを文曞化する適切な堎所はありたすか それはかなり頻繁に出おくる質問のようです。 うたくいけば、これがドキュメントに統合されおいれば、将来の問題が削枛される可胜性がありたすか

この解決策はうたくいきたせんでした。

テストファむル内では、 globalがJSDomのwindowオブゞェクトに蚭定されおいるようです。

぀たり、テストスむヌト内では、 globalはwindowず同じですが、 JSDOMEnvironmentを拡匵するクラス内では、 globalはノヌドの環境から取埗されたす。

結果ずしお、これを持っおいる

describe("test suite", () => {
  it("should not fail", () => {
    global.jsdom.reconfigure({
      url: "https://www.example.com/"
    });
  });
});

global.jsdomが未定矩であるため、倱敗したす。

私はこれを行うこずでそれを回避したしたが、私はそれに぀いおあたり倧隒ぎしおいたせん。

const JSDOMEnvironment = require("jest-environment-jsdom");

module.exports = class JSDOMEnvironmentGlobal extends JSDOMEnvironment {
  constructor(config) {
    super(config);

    this.dom.window.jsdom = this.dom;
  }
};

この環境では、テストスむヌト内のglobal.jsdomはthis.domず等しく、䞊蚘のテストスむヌトは機胜したす。

私には、 jsdomを独自のwindowオブゞェクトのプロパティに蚭定するこずは、最終的には厩壊するこずになりたす-それを行うためのよりクリヌンな方法はありたすか

テストでは、 global.jsdomではなくjsdomを蚘述する必芁がありたす。

@oliverzyこのように

describe("test suite", () => {
  it("should not fail", () => {
    jsdom.reconfigure({
      url: "https://www.example.com/"
    });
  });
});

それはjsdom is not definedスロヌしたすが、私は誀解しおいる可胜性がありたす。

@ simon360蚭定しおくださいtestEnvironment 、@oliverzyからコヌドを参照https://facebook.github.io/jest/docs/en/configuration.html#testenvironment -string

@danielbayerlein私のJest構成にはこれがありたす

"testEnvironment": "@wel-ui/jest-environment-jsdom-global"

ここで、 @wel-ui/jest-environment-jsdom-globalは、monorepo内のパッケヌゞの名前です。 ただし、 window jsdomを蚭定する゜リュヌションは期埅どおりに機胜するため、環境は正しく䜿甚されおいたす。

ずころで、元の゜リュヌションが新しいバヌゞョンで機胜しない理由を誰かが知っおいたすか
これです

Object.defineProperty(location, "hostname", {
  value: "example.com",
  writable: true
});

@modestfake JSDOM @ 9からJSDOM @ 11にアップグレヌドしたした。倉数の定矩方法が倉曎されたず思いたすが、

@SimenB了解したした。 jsdom reconfigureメ゜ッドの説明が芋぀かりたした。

りィンドりの䞀番䞊のプロパティは、仕様で[Unforgeable]ずマヌクされおいたす。これは、構成䞍可胜な独自のプロパティであるため、Object.definePropertyを䜿甚しおいる堎合でも、jsdom内で実行される通垞のコヌドによっおオヌバヌラむドたたはシャドりむングできないこずを意味したす。

この動䜜を瀺すために、新しいリポゞトリを远加したした。 ロヌカルでクロヌンを䜜成しお再珟できる人はいたすか

https://github.com/simon360/test-environment-for-jest

@ simon360再珟
image

@ simon360私が芋぀けたした。 global.jsdom定矩するずきにthisキヌワヌドを芋逃したした

const JSDOMEnvironment = require("jest-environment-jsdom");

module.exports = class JSDOMEnvironmentGlobal extends JSDOMEnvironment {
  constructor(config) {
    super(config);

    this.global.jsdom = this.dom;
  }

  teardown() {
    this.global.jsdom = null;

    return super.teardown();
  }
};

location.searchどうですか それに぀いおの蚀及は芋぀かりたせんでしたhttps://github.com/tmpvar/jsdom/blob/05a6deb6b91b4e02c53ce240116146e59f7e14d7/README.md#reconfiguring-the-jsdom-with-reconfiguresettings

@andrewBalekhaこれはどうですか

jsdom.reconfigure({
  url: 'https://www.example.com/endpoint?queryparam1=15&queryparam2=test'
});

ありがずう@ modestfake-ばかげた間違いでごめんなさい

わかりたした。わかりたした。Jest環境オブゞェクトのthis.global globalは、Jestテストファむルでnpmにjest-environment-jsdom-globalずしお配眮するこずができたす。

ただし、将来的にはJestでこれを行うためのよりクリヌンな方法があるこずを願っおいたす。 これは、 window.locationを倉曎するための䜎摩擊の方法ではありたせん-

@jest-environmentように、新しいdocblockがありたすか 䟋えば...

/**
 * @jest-url https://www.example.com/
 */

たたは、JSDomをjestオブゞェクトの特別な郚分に公開するこずもできたす。

jest.environment.jsdom.reconfigure({
  url: "https://www.example.com/"
});

これには、 window.topを倉曎できるずいう远加の利点がありたす

5003を統合したした。 docblockずしお远加できるこずは理にかなっおいるかもしれたせんが、確かではありたせん。 @cpojer testUrlも非掚奚にするこずができたす。これは、その新しいオプションを通じお提䟛できるためです。

十分な関心があれば、そのレポの修埩バヌゞョンをパッケヌゞ化しお、 npmにjest-environment-jsdom-globalずしお配眮するこずができたす。

いずれにせよ、URLを蚭定するだけでなく、完党なJSDOMを環境に公開するので、それは理にかなっおいるず思いたす。

@andrewBalekha Object.defineProperty(location, 'search', { ...options });は、 window.locationず同じ゚ラヌをスロヌしたす。 しかし、提案をありがずう。

Object.definePropertywindow.location、 'href'、{
setnewValue => {currentUrl = newValue; }、
};
以前のバヌゞョンでこれがありたしたが、゚ラヌが発生したす。
曞き蟌み可胜を远加した堎合true
アクセサず曞き蟌み可胜の䞡方を指定できないずいう別の䟋倖をスロヌしたす

私はnpmにjest-environment-jsdom-globalずいう新しいパッケヌゞを公開したした。これは、䞀郚の人々がObject.defineProperty抱えおいる問題に圹立぀可胜性がありたす。

{ writable: true }回避策はありたすか

䟋えば

Object.defineProperty(window.location, 'href', { writable: true })

...

Object.defineProperty(window.location, 'hash', { writable: true })

...

Object.defineProperty(window.location, 'search', { writable: true })

@danielbayerleinはこのスレッドを読んだ。 カスタム環境を䜜成する必芁がありたす。 前のメッセヌゞには䟋を含むURLが含たれおいたす

@modestfake私はすでにこのスレッドを読んでおり、 https //github.com/facebook/jest/issues/5124#issuecomment-352749005は正垞に機胜したす。 しかし、私には別のナヌスケヌスがありたす。 Jest 21.xxでは、URLなしでObject.defineProperty(window.location, 'href', { writable: true })を蚭定したした- { writable: true } 。 URLを蚭定した堎合、テストは意味がありたせん。

@danielbayerlein曞き蟌み可胜にするが、実際にはオヌバヌラむドしないようにするためのナヌスケヌスは䜕ですか たぶんこれを理解するこずは私が回避策を考え出すのを助けるこずができたす

URLを倉曎する関数がありたす。

routing.js

...

export function redirectToErrorPage () {
  window.location.href = '/error.html'
}

...

routing.test.js

test('redirect to the error page', () => {
  ...
  expect(window.location.href).toBe('/error.html')
  ...
})

Jest 21.xxで、 Object.defineProperty(window.location, 'href', { writable: true })

window.location.assignに切り替えるこずをお勧めしたす。そうすれば、関数をモックできたす。

@ simon360は魅力のように機胜したす ありがずう。 🀝

䜿甚したした

history.pushState({}, "page 2", "/bar.html");

jest蚭定のtestURLず䞀緒に

問題はロケヌション郚分だけではありたせん。 私はむンポヌトするこずはできたせんjsdom個別に呌び出すためのjsdom.reconfigureWindow その関数は、もはやjsdomの最新バヌゞョンに存圚するために。 window !== top堎合、異なる方法で実行されるコヌドをテストするためにこれを行っおいたした。 新しいバヌゞョンのjsdomを䜿甚する最新バヌゞョンのjestでこれを実珟する方法はもうありたせん。

@andyearnshaw jsdom.reconfigureメ゜ッドのオブゞェクトにはwindowTopメンバヌがありたす。

䞊でリンクしたJSDOM環境 jest-environment-jsdom-global を䜿甚しおいる堎合は、次のこずができたす。

jsdom.reconfigure({
  windowTop: YOUR_VALUE
});

あなたのテストで最高倀をモックアりトしたす。

私はそれを䜿甚しおいたす、そしおそれは玠晎らしい働きをしたす、ありがずう

2018幎1月30日火曜日、1340 simon360、 notifications @ github.comは次のように曞いおいたす。

@andyearnshaw https://github.com/andyearnshaw jsdom.reconfigure
メ゜ッドのオブゞェクトにはwindowTopメンバヌがありたす。

JSDOM環境jest-environment-jsdom-globalを䜿甚しおいる堎合I
䞊にリンクするず、次のこずができたす。

jsdom.reconfigure{
windowTopYOUR_VALUE
};

あなたのテストで最高倀をモックアりトしたす。

—
あなたが蚀及されたので、あなたはこれを受け取っおいたす。
このメヌルに盎接返信し、GitHubで衚瀺しおください
https://github.com/facebook/jest/issues/5124#issuecomment-361595999 、たたはミュヌト
スレッド
https://github.com/notifications/unsubscribe-auth/ABvdEzCLlWtzr0udscL0C6KUxpgXHZRhks5tPxvJgaJpZM4RGN7C
。

window.history.pushStateずtestUrlうたくいきたした

https://github.com/facebook/jest/issues/5124#issuecomment -359411593

Jest偎には䜕もするこずがなく、回避策が存圚するため、これを閉じたす議論を続けおください

jsdom v8.5.0からv11.6.2にアップグレヌドするず、問題が解決したした。 したがっお、私のpackage.jsonは次のものが含たれたす。

"jest": "^21.2.1",
"jest-cli": "^21.2.1",
"jsdom": "^11.6.2",

jestずjest-cliをv22.2.2にアップグレヌドするず壊れたす。

@ andr-3-w package.jsonにjsdomがある特別な理由はありたすか Jestにバンドルされおいたす。

@SimenBは、質問良い、のための必芁はありたせんjsdom私たちの䞭にpackage.json 。 ありがずう

したがっお、jsdomを盎接䜿甚せずに、これが私が自分のもののために思い぀いた解決策です

Jest 21.2.1で動䜜したす私はそれでテストしたした

Jest蚭定に移動したすたずえば、package.jsonを䜿甚したす。

"jest": { "testURL": "http://localhost" }

これで、window.locationオブゞェクトを倉曎できるようになり、テスト䞭にURLを奜きなように蚭定できたす。

it('Should set href url to testURL', () => {
    // Here I set href to my needs, opinionated stuff bellow
    const newUrl = 'http://localhost/editor.html/content/raiweb/it/news/2018/02/altered-carbon-best-cyberpunk-tv-series-ever.html';
    Object.defineProperty(window.location, 'href', {
        writable: true,
        value: newUrl
    });

    console.log(window.location.href);
});

it('Should set pathname url to testURL', () => {
    // Here I set href to my needs, opinionated stuff bellow
    const newUrl = '/editor.html/content/raiweb/it/news/2018/02/altered-carbon-best-cyberpunk-tv-series-ever.html';
    Object.defineProperty(window.location, 'pathname', {
        writable: true,
        value: newUrl
    });

    console.log(window.location.pathname);
});

うたくいけば、これは誰かを助けたす。

これを投皿するのをやめおください、それはjestでは機胜したせん "" ^ 22.4.2 "

@UserNTここで動䜜するバヌゞョンを

完党を期すために、゜リュヌションはこのスレッドの途䞭で取り残されおいるため...

@ petar-prog91の゜リュヌションは、Jest 21で機胜したすが、曎新されたjsdom Jest22では機胜したせん。

最新の冗談䞊で実行するために、䜿甚のようなものjest-environment-jsdom-global 、これは私のパッケヌゞの完党な開瀺であるを露出するためにjsdomオブゞェクトを䜿いjsdom.reconfigure持っおいるであろうが、同じたたは少なくずも同様の効果。

https://github.com/facebook/jest/issues/5124#issuecomment-359411593は私のためにjest22でも動䜜したす

@ simon360こんにちは、 location.hrefのセッタヌをハックする必芁がある堎合はどうすればよいですか
私の以前のテストにはこのような倚くのテストがあり、今ではすべお倱敗しおいたす...

const setHrefMockFn = jest.fn();
beforeAll(() => {
  Object.defineProperty(location, "href", {
    get: () => "https://xxxxx",
    set: setHrefMockFn
  });
});
it("xxx", () => {
  //...
  expect(setHrefMockFn.mock.calls[0][0]).toBe(xxx);
});

@ simon360ラむブラリで以䞋のようなテストを曎新する方法の䟋を教えおください

beforeAll(() => {
  =======

  Object.defineProperty(window.location, 'href', {
    writable: true
  });
});

@abhijeetNmishraドキュメントを芋たこずがあり

@ simon360はい、ドキュメントの私の理解に基づいお、それは玄かかりたす

jsdom.reconfigure({
      url: "https://www.example.com/"
    });

これは、テストごずではなく、グロヌバルにURLをオヌバヌラむドしたす。 助けおください

@abhijeetNmishraこの問題が議論するのに最適な堎所かどうかはjest-environment-jsdom-globalリポゞトリで問題を開いおいただけたせんか。 ありがずう

@SimenBに蚘茉されおいる回避策「 jest-environment-jsdom-global 」は、明らかに非垞に䞀般的な問題に察する非垞に最適ではない解決策のように感じたす。 Jest 22にアップグレヌドする人は誰でも、そのサヌドパヌティパッケヌゞに䟝存関係を远加し、ナヌザヌの芳点からテストの䞀郚を曞き盎す必芁がありたす。 これは、Jestの動䜜の回垰です。

デフォルトのjest-environment-jsdom組み蟌むこずができるこれに察する解決策はありたすか あなたの指導でPRをしお幞せです。

window.location.hrefを倉曎するためだけに、この倚くのフヌプを誰かがゞャンプしなければならないのは非垞に残念です。 Jestを䜿い始めたばかりで、この問題を考慮しお、テストフレヌムワヌクの遞択を再怜蚎しようずしおいたす。 䞊で提案された醜いハックよりも良い解決策は本圓にありたせんか

@ydogandjievは、この問題を解決するためのプロゞェクトに気軜に貢献しおください。 これはオヌプン゜ヌスであるこずを忘れないでください。「受け入れられない」や「ばかげおいる」などのコメントで暎れ回っおも、だれにも圹立ちたせん。

@ msholty-fdできれば手䌝いたいです。 私はjestずjsdomを始めたばかりなので、これらのラむブラリを十分に理解しお、この゚クスペリ゚ンスを改善するための最良のルヌトが䜕であるかを正確に知るこずができるかどうかはわかりたせん。 これは、jestたたはjsdomで最も適切に察凊されるものですか これらのラむブラリの1぀が、ある時点でObject.definePropertyアプロヌチを壊した倉曎を加えたようです。 それはjestたたはjsdomで行われた倉曎でしたか

したがっお、window.locationを倉曎するために必芁な行数に基づいお、私が奜たしいず考えるすべおのオプションがありたす。 これらのどれも珟圚機胜したせん

  1. jsdomが「゚ラヌ実装されおいたせんナビゲヌションハッシュの倉曎を陀く」ずいうメッセヌゞで䟋倖をスロヌするため、hrefを盎接蚭定するこずはできたせん。
    window.location.href = "https://www.example.com";
  1. JSDOMがりィンドりのロケヌションプロパティを䜜成したため、Object.definePropertyの䜿甚は機胜したせん[Unforgeable] 

    Object.defineProperty(window.location, "href", {
      value: "https://www.example.com",
      configurable: true
    });
    
  2. jestは、簡単にアクセスできるように公開されおいない独自のむンスタンスを䜿甚しおいるように芋えるため、jsdomのむンスタンスを䜜成しお構成するこずはできたせん。

    import { JSDOM } from "jsdom";
    ...
    const dom = new JSDOM();
    dom.reconfigure({ url: "https://www.example.com" });
    

オプション1たたは2を機胜させるには、jsdomが、実際のブラりザヌのように動䜜するずいう珟圚の目暙に戻る必芁がありたす。 したがっお、私たちが持っおいる唯䞀のオプションは、jestが䜿甚するjsdomのむンスタンスを簡単に再構成できるようにするこずのようです。 そのむンスタンスをグロヌバルjestオブゞェクトに盎接公開するこずは理にかなっおいたすか。 ぀たり、次のようなものを蚱可したす。

jest.dom.reconfigure({ url: "https://www.example.com" });

私はただlocation.assign('some-url')を行う方がlocation.href = 'some-url'よりも優れおいるず思いたす。 割り圓およりも明瀺的な関数呌び出しを芋぀けたした。関数をモックできたす

@SimenBは、コヌドがlocation.hrefを_set_しようずしおいる堎合、はい、 location.assign()方が優れおいたす。 しかし、 location.hrefを_読み取る動䜜をテストしおいる堎合、特にJSDOMのlocation.assign()は実際には䜕もしないため、 location.assign()は問題を解決したせん。

reconfigureを䜿甚する背埌にある考え方は、 location.hrefが特定の方法で圢成された堎合にのみ有効になるコヌドパスをアクティブ化するこずです。 私たちの堎合、珟圚のドメむンに応じお倉曎されたコヌドがありたした-コヌドは臭いです、はい、しかしそれも必芁です、そしお臭いコヌドを軜枛するための最良の方法は、動䜜をキャプチャしおそれがずどたるこずを確認するテストフィクスチャを持぀こずです所定の䜍眮に。

Enzymeずマりントされたコンポヌネントでこれを䜿甚しおリダむレクトをテストする方法はありたすか

Jestをアップグレヌドする前に、以䞋のテストに合栌したした。

`` `
it '正しいルヌトぞのルヌト'、=> {

Object.defineProperty(window.location, 'href', {
  writable: true,
  value: 'https://mysuperawesomesite.com/',
});

const component = mount(
  <App {...props} />
);

const link = component.find('.class');

link.simulate('click');

expect(window.location.href).toEqual('https://mysuperawesomesite.com/new');

};

After upgrading Jest and implementing [jest-environment-jsdom-global](https://www.npmjs.com/package/jest-environment-jsdom-global), I tried the following to no avail:

  ```
it('routes to correct route', () => {

    jsdom.reconfigure({
      url: 'https://mysuperawesomesite.com/',
    });

    const component = mount(
      <App {...props} />
    );

    const link = component.find('.class');

    link.simulate('click');

    expect(window.location.href).toEqual('https://mysuperawesomesite.com/new');
  });

window.location.hrefはただ ' https://mysuperawesomesite.com/ 'に等しく、 'https://mysuperawesomesite.com/new'に倉曎されたせんでした。

このメ゜ッドを䜿甚する堎合、芁玠のクリックむベントはリダむレクトされたせん。リダむレクトは、window.location.hrefを蚭定するこずで発生したす。

これを適切にテストする方法、たたは以前にObject.definePropertyを䜿甚したテストが最初から䞍十分に構築されおいるかどうかが䞍明です。 よろしくお願いしたす。

線集解決枈み

window.location.href = hrefの代わりにwindow.location.assignurlを䜿甚するこずで、これを解決できたした。 これにより、assignメ゜ッドをスタブアりトしお、適切に呌び出されおいるかどうかをテストできたした。 䞋蚘参照

it('routes to correct route', () => {
    window.location.assign = jest.fn();

    const component = mount(
      <App {...props} />
    );

    const link = component.find('.class');

    link.simulate('click');

    expect(window.location.assign).toBeCalledWith('https://mysuperawesomesite.com/new');
    window.location.assign.mockRestore();
  });

@SimenB .assignず.hrefは倧きな違いがありたす。MDNで読むこずができたす。 最初のものには、䞻芁なクロスドメむン制限がありたす。 私のコヌドでは、コヌドが実行されおいるiframeから芪ペヌゞをリダむレクトしたいず思いたす。 それらはクロスドメむンです。 そしお、これを行う唯䞀の方法は、 href倉曎するこずです。
珟圚の回避策が芋圓たらず、この機胜のテストを行わないようにする必芁があるため、この問題を再床開いおいただければ幞いです。 これは明らかにひどいです。

私は@soswowず同じ船に乗っおいたす。 この機胜が埩元されるたでいく぀かの単䜓テストも削陀するので、URLをオヌバヌラむドするメカニズムを提䟛できれば玠晎らしいず思いたす。

珟圚の回避策が芋圓たらず、この機胜のテストを行わないようにする必芁があるため、この問題を再床開いおいただければ幞いです。 これは明らかにひどいです。

冗談の偎で私たちにできるこずは䜕もありたせん。 jsdomはそれをサポヌトするPRが倧奜きだず確信しおいたす。 https://github.com/jsdom/jsdom/issues/2112

これが機胜する簡単な解決策です。

describe('changing location', () => {
  const testURL = location.href;

  beforeEach(() => history.replaceState({}, 'Login', '/login'));
  afterEach(() => history.replaceState({}, 'Home', '/'));

  it('works', () => {
    expect(location.pathname).toBe('/login');
  });
});

@vastus私が明瀺的に指摘したように、問題はクロスドメむンにありたす。 履歎APIでは、私が芚えおいる限り、別のドメむンに切り替えるこずはできたせん。

locationはjsdom windowオブゞェクトで盎接オヌバヌラむドできないため、1぀の可胜なアプロヌチは、掟生オブゞェクトでオヌバヌラむドするこずです。

global.window = Object.create(window);
Object.defineProperty(window, 'location', {
  value: {
    href: 'http://example.org/'
  }
});

私はこれを䜿っお問題を解決したす

const windowLocation = JSON.stringify(window.location);
delete window.location;
Object.defineProperty(window, 'location', {
  value: JSON.parse(windowLocation)
});

@ RubenVerborgh  annemarie35に觊発された

@vastusの゜リュヌションに基づいおlocation.searchをテストする䟋を远加したす。

  test('gets passed query param and returns it as a string if it exists', () => {
    history.replaceState({}, 'Test', '/test?customer=123');
    const customerId = getQueryParam('customer');
    expect(customerId).toBe('123');
  });

@RubenVerborghは魅力のように機胜したす。

詊す

window.history.pushState({}, null, '/pathname?k=v');

@sahalsaadに䌌た解決策
`` `javascript
const oldWindow = window.location;
window.locationを削陀したす。
window.location = {
... oldWindow、
//次のsinonスタブなどのカスタム䞊曞きを含める
眮換sinon.stub、
};

//魔法をかける

window.location = oldWindow;
`` ``

@sahalsaadありがずう 私はあなたの゜リュヌションのバリ゚ヌションを䜿甚しおwindow.location.searchをモックしたした

const location = {
    ...window.location,
    search: queryString,
};
Object.defineProperty(window, 'location', {
    writable: true,
    value: location,
});

おそらくより良い解決策

import { URL } from 'whatwg-url';

const location = new URL(window.location.href);
location.assign = jest.fn()
location.replace = jest.fn()
location.reload = jest.fn()

delete window.location
window.location = location

@kdelmonteによっおwindow.location.search倉数をモックする必芁がありたした。 だから私は䜿甚したした

window.history.pushState({}, null, '?skuId=1234')

locationはjsdom windowオブゞェクトで盎接オヌバヌラむドできないため、1぀の可胜なアプロヌチは、掟生オブゞェクトでオヌバヌラむドするこずです。

global.window = Object.create(window);
Object.defineProperty(window, 'location', {
  value: {
    href: 'http://example.org/'
  }
});

あなたの答えは私の状況に圹立぀唯䞀のものです、ありがずう

locationはjsdom windowオブゞェクトで盎接オヌバヌラむドできないため、1぀の可胜なアプロヌチは、掟生オブゞェクトでオヌバヌラむドするこずです。

global.window = Object.create(window);
Object.defineProperty(window, 'location', {
  value: {
    href: 'http://example.org/'
  }
});

あなたの答えは私の状況に圹立぀唯䞀のものです、ありがずう

これはもう機胜したせん😢

locationはjsdom windowオブゞェクトで盎接オヌバヌラむドできないため、1぀の可胜なアプロヌチは、掟生オブゞェクトでオヌバヌラむドするこずです。

global.window = Object.create(window);
Object.defineProperty(window, 'location', {
  value: {
    href: 'http://example.org/'
  }
});

あなたの答えは私の状況に圹立぀唯䞀のものです、ありがずう

これはもう機胜したせん😢

私のためにも働いおいない

私はこれをやっお解決したした

delete window.location
window.location = {
  href: 'http://example.org/,
}

Locationためのナヌティリティずしお次のモックを䜿甚しおいたす

export class MockLocation extends URL implements Location {
  ancestorOrigins: any = []
  toString = jest.fn().mockImplementation(() => this.toString())
  assign = jest.fn(href => this.href = href)
  replace = jest.fn(href => this.href = href)
  reload = jest.fn()

  constructor(
    url: string = 'http://mock.localhost',
  ) {
    super(url)
  }

  onWindow(window: Window) {
    Object.defineProperty(window, 'location', { 
      writable: true,
      value: this
    });
    return this
  }
}

それから私のテストでは

let location: MockLocation

beforeEach(() => {
    location = new MockLocation(MOCK_PARTNER_URL).onWindow(window)
})

私はい぀もこのようなトリッキヌなオブゞェクトをスタブしおいるこずに気づき、柔軟なヘルパヌ関数を䜜成したした。

export const safelyStubAndThenCleanup = (target, method, value) => {
  const original = target[method]
  beforeEach(() => {
    Object.defineProperty(target, method, { configurable: true, value })
  })
  afterEach(() => {
    Object.defineProperty(target, method, { configurable: true, value: original })
  })
}

そしお䜿甚法

describe('when on /pages', () => {
  safelyStubAndThenCleanup(window, 'location', { pathname: '/pages' })

  it('should do something neat', () => { /* ... */ })
})

そしお、あなたはあなたが望むものを䜕でもスタブするこずができたす pathname 、 hrefなど...これはあなたにクリヌンアップの远加の無料の利点をもたらしたす。

重芁なのは、 location自䜓を台無しにするこずはできないので、 locationを停物ず亀換し、テストが完了したら元に戻すだけです。

デバッグセッションでわかるように、 global.locationはgetterを介しお実装されおいたすが、単玔なプロパティではありたせん。 このように再定矩する方が安党ではないでしょうか。

let originalLocationDescriptor;
beforeAll(() => {
  originalLocationDescriptor = Object.getOwnPropertyDescriptor(global, 'location');
  delete global.location;
  global.location = {};
});
afterAll(() => {
  Object.defineProperty(global, 'location', originalLocationDescriptor);
}):

元のglobal.locationを䜿甚する理由を想像するのは難しいですが、もう少し正しいようです。
もちろん、このコヌドは私にずっおは問題なく機胜したす。 location.pathnameにアクセスするだけですが、このオブゞェクトは、必芁に応じおjest.fn()で簡単に拡匵できたす。

これは、jest26.5を䜿甚しお私のために働いおいたす

function stubLocation(location) {
  beforeEach(() => {
    jest.spyOn(window, "location", "get").mockReturnValue({
      ...window.location,
      ...location,
    });
  });
}

stubLocation({ pathname: "/facebook/jest/issues/5124" });

test("mocks location prop", () => {
  expect(window.location.pathname).toEqual("/facebook/jest/issues/5124");
});

@vastusの゜リュヌションに基づいおlocation.searchをテストする䟋を远加したす。

  test('gets passed query param and returns it as a string if it exists', () => {
    history.replaceState({}, 'Test', '/test?customer=123');
    const customerId = getQueryParam('customer');
    expect(customerId).toBe('123');
  });

これは私が抱えおいた問題に察しお正確にうたくいきたした

このペヌゞは圹に立ちたしたか
0 / 5 - 0 評䟡