vitest vi.spyOn 没有副作用吗?

mic*_*urs 5 javascript mocking typescript spyon vitest

我想使用“vi.spyOn”来监视对模块中 sideEffect 函数的调用,以确保模块中的另一个函数正在调用。

我在 jest 上这样做没有问题,但它似乎在 vitest 上不起作用。

这是一个简化的例子

aModule.ts

export function a() {
  return sideEffect();
}

export function sideEffect() {
  return 'a';
}
Run Code Online (Sandbox Code Playgroud)

这是测试文件:

import { vi, expect, test } from 'vitest';
import * as aModule from '../src/aModule';

test('expect "sideEffect" to be called at least once', async () => {
  const sideEffectSpy = vi.spyOn(aModule, 'sideEffect').mockReturnValue('b');
  const aSpy = vi.spyOn(aModule, 'a');

  const res = aModule.a(); // This function calls sideEffect internally.
  expect(res).toBe('b'); // This fails - it returns 'a' so the spyOn is not workng
  expect(sideEffectSpy).toHaveBeenCalled(); // This fails as well :( 
});
Run Code Online (Sandbox Code Playgroud)

我确实尝试了一些变体,但无法使其工作。有任何想法吗?

谢谢。

Tua*_*ham 0

这是等待此错误修复时的解决方法:移至sideEffect单独的模块,例如bModule.ts.

export function sideEffect() {
  return "a";
}
Run Code Online (Sandbox Code Playgroud)

然后aModule.ts

import { sideEffect } from './bModule';
export function a() {
  return sideEffect();
}
Run Code Online (Sandbox Code Playgroud)

aModule.test.ts

import { vi, expect, test } from "vitest";
import * as aModule from "./aModule";
import * as bModule from "./bModule";

test('expect "sideEffect" to be called at least once', async () => {
  const sideEffectSpy = vi.spyOn(bModule, "sideEffect").mockReturnValue("b");

  const res = aModule.a(); // This function calls sideEffect internally.
  expect(res).toBe("b"); // This now passes - it returns 'b'
  expect(sideEffectSpy).toHaveBeenCalled(); // This passes as well :)
});
Run Code Online (Sandbox Code Playgroud)