182 votes

Comment simuler window.location.href avec Jest + Vuejs ?

Actuellement, je suis en train d'implémenter un test unitaire pour mon projet et il y a un fichier qui contenait window.location.href .

Je veux faire une simulation pour tester et voici mon exemple de code :

it("method A should work correctly", () => {
      const url = "http://dummy.com";
      Object.defineProperty(window.location, "href", {
        value: url,
        writable: true
      });
      const data = {
        id: "123",
        name: null
      };
      window.location.href = url;
      wrapper.vm.methodA(data);
      expect(window.location.href).toEqual(url);
    });

Mais je reçois cette erreur :

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

J'ai essayé quelques solutions mais je ne l'ai pas résolu. J'ai besoin de quelques conseils pour m'aider à me sortir de ce mauvais pas. Aidez-moi, s'il vous plaît.

1 votes

Cette question a été traitée dans un autre fil de discussion Voici le lien vers la réponse

4 votes

Ce n'est pas exactement ce que vous recherchez mais window.location.assign(url) fait fonctionnellement la même chose, vous pouvez donc le simuler à la place en utilisant la fonction jest.spyOn(window.location, 'assign').mockImplementation(() => {});

16voto

Devin Clark Points 141

Exemple de travail avec @testing-library/react en 2020 pour window.location.assign :

  afterEach(cleanup)
  beforeEach(() => {
    Object.defineProperty(window, 'location', {
      writable: true,
      value: { assign: jest.fn() }
    })
  })

3 votes

writable: true était nécessaire pour que mes tests unitaires fonctionnent, sinon les tests suivants ne seraient pas en mesure de l'écraser par quelque chose d'autre. Merci

12voto

Juan Lago Points 74

De nombreux exemples fournis ne reprennent pas les propriétés de l'objet Location original.

Ce que je fais, c'est simplement remplacer l'objet Location (window.location) par URL, car URL contient les mêmes propriétés que l'objet Location comme "href", "search", "hash", "host".

Les Setters et Getters fonctionnent également exactement comme l'objet Location.

Exemple :

const realLocation = window.location;

describe('My test', () => {

    afterEach(() => {
        window.location = realLocation;
    });

    test('My test func', () => {

        // @ts-ignore
        delete window.location;

        // @ts-ignore
        window.location = new URL('http://google.com');

        console.log(window.location.href);

        // ...
    });
});

1 votes

Je me demande si ça ne devrait pas être const realLocation = Object.assign({}, window.location); car j'ai l'impression que l'assigner directement reviendrait à transmettre une référence qui sera écrasée par la suite. Qu'en pensez-vous ?

0 votes

L'objet vers lequel pointe window.location n'est pas modifié dans ce code - la propriété window.location contient des objets différents. Puisqu'il n'y a pas de mutation de l'objet original window, il n'y a pas besoin de le cloner.

4voto

thisismydesign Points 751

Extension de la solution de @jabacchetta pour éviter que ce paramètre ne se répande dans d'autres tests :

describe("Example", () => {
  let location;

  beforeEach(() => {
    const url = "https://example.com";
    location = window.location;
    const mockLocation = new URL(url);
    mockLocation.replace = jest.fn();
    delete window.location;
    window.location = mockLocation;
  });

  afterEach(() => {
    window.location = location;
  });
});

2voto

lequan Points 28

Vous pouvez essayer une aide :

const setURL = url => global.jsdom.reconfigure({url});

describe('Test current location', () => {
  test('with GET parameter', () => {
    setURL('https://test.com?foo=bar');
    // ...your test here
  });
});

1voto

Estevão Lucas Points 1621

Ceci est valable pour Jest + TypeScript + Next.js (au cas où vous utilisez useRoute().push

const oldWindowLocation = window.location;

beforeAll(() => {
  delete window.location;
  window.location = { ...oldWindowLocation, assign: jest.fn() };
});

afterAll(() => {
  window.location = oldWindowLocation;
});

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X