我有以下代碼
main.ts
export const add = (x: number, y: number): number => {
return x y;
}
export const minus = (x: number, y: number): number => {
return x - y;
}
export const calculate = (x: number, y: number, operator: string) => {
let result = -1;
switch (operator) {
case ' ':
result = add(x, y);
break;
case '-':
result = minus(x, y);
break;
}
return result;
}
我想寫下面的測驗
main.test.ts
import {calculate} from "./main";
jest.mock("./main", () => ({
...jest.requireActual("./main"),
add: function () {
return 17;
}
}));
describe('testing', function () {
it('should test', function () {
const result = calculate(3, 2, ' ');
expect(result).toBe(5);
});
});
我想做部分模擬,我模擬 add() 函式,但我不想使用計算的實際實作()。但它對我不起作用,add(3,2) 只回傳 5,而不是 17。我猜是因為它們都來自同一個模塊。
我知道我可以使用 jest.spyOn() 但我想了解為什么 jest.mock() 不起作用以及如何解決它
uj5u.com熱心網友回復:
mock不會替換原始源代碼檔案,只會添加一個新的模擬版本。
import { add } from './main';
jest.mock('./main', () => {
const actual = jest.requireActual('./main');
return {
// ...actual,
add: function () {
return 17;
}
};
});
describe('add', () => {
it('should use the mocked add function', () => {
expect(add(1, 2)).toBe(17);
});
it('should use the original add function', async () => {
const main = jest.requireActual('./main');
expect(main.add(1, 2)).toBe(3);
});
});
在您的模擬工廠函式中,您替換add了 ,但您使用了calculate呼叫原始函式的原始add函式。這就是為什么add不使用模擬函式的原因。
要使其按您想要的方式作業,您還必須替換calculate(以便它可以使用新add功能),例如:
import { add, calculate, minus } from './main';
jest.mock('./main', () => ({
//__esModule: true,
...jest.requireActual('./main'),
calculate: function (x: number, y: number, operator: string) {
let result = -1;
switch (operator) {
case ' ':
result = add(x, y);
break;
case '-':
result = minus(x, y);
break;
}
return result;
},
add: function () {
return 17;
}
}));
describe('calculate', () => {
it('should use the mocked calculate and add function', () => {
const result = calculate(3, 2, ' ');
expect(result).toBe(17);
});
});
由于所有這些替換都令人困惑且容易出錯,因此您應該真正使用它jest.spyOn。
參考這個答案
對匯入的模塊進行變異是令人討厭的,并且可能會導致副作用,例如根據執行順序通過或失敗的測驗。
邊注
如果您真的想這樣做,那么您至少應該將運算子和計算函式移動到不同的檔案中。然后你只需要模擬運算子模塊。
operators.ts:
export function add(x: number, y: number): number {
return x y;
}
export const minus = (x: number, y: number): number => {
return x - y;
};
calculate.ts:
import { add, minus } from './operators';
export const calculate = (x: number, y: number, operator: string) => {
let result = -1;
switch (operator) {
case ' ':
result = add(x, y);
break;
case '-':
result = minus(x, y);
break;
}
return result;
};
calculate.spec.ts:
import { calculate } from './calculate';
jest.mock('./operators', () => ({
//__esModule: true,
...jest.requireActual('./operators'),
add: function () {
return 11;
}
}));
describe('calculate', () => {
it('should use the mocked add function', () => {
const result = calculate(3, 2, ' ');
expect(result).toBe(11);
});
});
uj5u.com熱心網友回復:
您可以通過使用通配符別名匯入來實作此目的:
import * as calculation from "./main";
describe('testing', function () {
it('should test', function () {
jest.spyOn(calculation, 'add').mockImplementation(() => 17)
const result = calculation.calculate(3, 2, ' ');
expect(result).toBe(5);
});
});
因為沒有默認匯入,您可以簡單地將其更改為通配符 ( *) 別名 ( as),然后顯式監視要模擬的函式并mockImplementation用來模擬它的行為方式。如果您希望它的行為是一致的,您也可以移動jest.spyOn(calculation, 'add').mockImplementation(() => 17)到函式上方。describe
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/490951.html
