この記事はもう古くなってしまいました。
Jest v28 以降では、下記のように JSDOM のオプションを指定することができるようになっています。

/**
 * @jest-environment jsdom
 * @jest-environment-options {"url": "https://example.com/"}
 */
it('detects PC', () => {
  expect(location.hostname).toBe('example.com');
});

目的

Node.js におけるテストで Jest を使用する場合、DOM API が関連するテストは JSDOM の実装によって実行されます。この JSDOM はブラウザーと完全に同じ実装を持っているわけではなく、location.href への代入ができないなどの制約があります。そのため Jest でもこれに合わせて JSDOM の API を使用したテストコードを記述する必要があります。

準備

Jest では JSDOM の API を直接参照することができないため、jest-environment-jsdom-global をインストールします。

$ npm i jest-environment-jsdom-global jest-environment-jsdom

package.jsonjest の項目にも追加しておきます。

{
  "jest": {
    "testEnvironment": "jest-environment-jsdom-global"
  }
}

書き方

あとは location プロパティーなどのように書き換えることができないものを jsdom.reconfigure() を使って書き換えます2。これは location.href を直接使えるようになるわけではなく、上記パッケージによって jsdom が Jest から参照できるようになるというだけです。

it('detects PC', () => {
  jsdom.reconfigure({
    url: 'https://example.com/',
  });

  expect(location.hostname).toBe('example.com');
});

it('detects SP', () => {
  jsdom.reconfigure({
    url: 'https://sp.example.com/',
  });

  expect(location.hostname).toBe('sp.example.com');
});

パス部分の書き換えだけであれば history.pushState() を使用することでも対処できますが、ホスト名の書き換えなどを伴う場合は jsdom.reconfigure() が必要です。

脚注