基于這個問題(如何模擬用 jest.mock 模擬的類的實體方法?),如何在保持所有其他方法的實作的同時模擬特定方法?
有一個類似的問題(Jest: How to mock one specific method of a class),但這僅適用于類實體在其呼叫類之外可用的情況,因此如果類實體位于此問題中的建構式內部,則此方法不起作用(如何使用 jest 模擬建構式實體化的類實體?)。
例如,Logger該類被模擬為只有method1模擬但隨后method2丟失,從而導致錯誤:
// Logger.ts
export default Logger() {
constructor() {}
method1() {
return 'method1';
}
method2() {
return 'method2';
}
}
// Logger.test.ts
import Logger from './Logger';
jest.mock("./Logger", () => {
return {
default: class mockLogger {
method1() {
return 'mocked';
}
},
__esModule: true,
};
});
describe("Logger", () => {
it("calls logger.method1() & logger.method2 on instantiation where only method1 is mocked", () => {
const logger = new Logger(); // Assume this is called in the constructor of another object.
expect(logger.method1()).toBe('mocked');
expect(logger.method2()).toBe('method2'); // TypeError: logger.method2 is not a function.
});
});
一種解決方案是擴展Logger類,但這會導致undefined錯誤,因為Logger已經模擬了:
// ...
jest.mock("./Logger", () => {
return {
default: class mockLogger extends Logger {
override method1() {
return 'mocked';
}
},
__esModule: true,
};
});
// ...
expect(logger.method2()).toBe('method2'); // TypeError: Cannot read property 'default' of undefined
method1因此,僅模擬但保留method2原始實作的正確方法是什么?
uj5u.com熱心網友回復:
您可以使用jest.requireActual要求原始模塊,然后method2在模塊工廠內部使用原始實作。
import Logger from "./Logger";
jest.mock("./Logger", () => {
const { default: originalLogger } = jest.requireActual("./Animal.js");
return {
default: class mockLogger {
method1() {
return "mocked";
}
method2() {
orginalLogger.prototype.module2();
}
},
__esModule: true,
};
});
describe("Logger", () => {
it("calls logger.method1() & logger.method2 on instantiation where only method1 is mocked", () => {
const logger = new Logger();
expect(logger.method1()).toBe("mocked");
expect(logger.method2()).toBe("method2");
});
});
uj5u.com熱心網友回復:
模擬原型作品:
describe("Logger", () => {
it("calls logger.method1() & logger.method2 on instantiation where only method1 is mocked", () => {
Logger.prototype.method1 = jest.fn(() => 'mocked');
const logger = new Logger();
expect(logger.method1()).toBe('mocked');
expect(logger.method2()).toBe('method2');
});
});
但是,我不確定這是否是在無法訪問類實體時模擬特定方法的正確方法,所以我會暫時保留這個問題,以防有更好的解決方案。
轉載請註明出處,本文鏈接:https://www.uj5u.com/gongcheng/477572.html
標籤:javascript 打字稿 单元测试 开玩笑的 嘲弄
上一篇:抽象類中的C#Moq方法
