我正在使用打字稿和玩笑。我正在尝试执行一个非常简单的单元测试,但是它总是失败。这是我的代码:
// init.ts
let initialized = false;
let secretName: string;
export function init(name: string) {
if (initialized) {
throw new Error("Cannot re-initialize.");
}
secretName = name;
initialized = true;
}
export function getSecret(): string {
return secretName;
}
// init.test.ts
describe("init", () => {
async function getTestSubject() {
return await import("./init");
}
it("should set the secret name properly", async () => {
const init = await getTestSubject();
init.init("bruce wayne");
expect(init.getSecret()).toEqual("bruce wayne");
});
it("should throw an exception if initialized more than once", async () => {
const init = await getTestSubject();
const callInit = function() {
init.init("bruce wayne");
};
callInit();
expect(callInit).toThrowError("Cannot re-initialize.");
});
});
第二单元测试由于抛出异常而失败。当第一次调用“ callInit()”时,应该是第一次对该单元测试调用init。但是,这是第二次在考虑两个单元测试时调用它。
我认为,通过在每个测试中动态导入测试主题(例如“ ./init”),我避免了这个问题,因为我最初尝试像这样在顶部导入init:
import {init, getSecret} from "./init";
关于如何测试的任何想法?我认为这是一个非常基本的测试用例,所以在玩笑方面有很大的限制,或者我只是缺少明显的东西...
谢谢!
您的第二次测试失败,因为您正在打电话:
callInit();
由于您多次初始化它而引发异常。
删除该行,然后删除您的期望,即
expect(callInit).toThrowError("Cannot re-initialize.");
应该工作。
我能够通过在jest.resetModules()
中调用jest.resetModules()
以便在每次测试之前重置模块名称空间来使其正常工作。
beforeEach()
您是正确的,这里有必要内联导入其他模块,因为使用标准ES6导入无法完成模块名称空间的此重置。但是在上面的示例中,我使用了我认为更简单的beforeEach(() => {
jest.resetModules()
})
it('should set the secret name properly', () => {
const initModule = require('./init')
initModule.init('bruce wayne')
expect(initModule.getSecret()).toEqual('bruce wayne')
})
it('should throw an exception if initialized more than once', () => {
const initModule = require('./init')
const callInit = () => initModule.init('bruce wayne')
callInit()
expect(callInit).toThrowError('Cannot re-initialize.')
})
方法。