📑

一日一処: Vitestで巻き上げ(hoisted)したのはいいけど、ほかのMockが呼び出せない(クロージャできない)問題の解決

2024/03/08に公開

hoistedで作成したMockからは外部が呼び出せない

たとえば、以下の状況だ。

describe('main', () => {
  const addMessage = vi.fn();
  const { main } = vi.hoisted(() => ({
    main: vi.fn((name: string) => {
      addMessage(`hello, ${name}`);
    }),
  }));

  main('test');
});

ある関数の検証を行うとき、その関数内で、他の関数を呼び出し、更に、他の関数を呼び出した際、元の関数では、データを加工する。このとき、データが加工されているのか知りたい場合がある。だが、巻き上げを行っている場合、スコープが異なってしまうため、上記の例だい、mainからaddMessageが呼び出せず、undefinedとなる。

解決した方法

もしかしたら、他にも解決できる方法があるかもしれないが、今回はこのように対処した。

describe('main', () => {
  const { main, addMessage } = vi.hoisted(() => ({
    addMessage: vi.fn(),
    main: vi.fn((name: string) => {
      addMessage(`hello, ${name}`);
    }),
  }));

  test('shuold called addMessage', () => {
    main('Otanisan');
    expect(addMessage).toBeCalledWith('hello, Otanisan')
  })
});

ともに巻き上げができれば、呼び出すことができ、テストに使用することができる。他には、オブジェクトなどもhoistedで渡すことができるので、オブジェクトの内容を変えつつ、結果を検証することもできるだろう。
個人的にはあまりスッキリする方法とは思えないので、もし、他の方法を知っている方がいれば、コメントで教えてほしい。

Discussion