如何在Jest中将express-session的可选方法模拟为undefined?
问题:如何模拟sessionStore中不存在的clear方法?
我正在为使用express-session包的NestJS/Express服务器编写单元测试,sessionStore对象的clear方法可能未定义。业务代码会先检查该方法是否存在再调用,代码如下:
clearAllSessions(): Promise<string> { return new Promise<string>((resolve, reject) => { if (this.sessionStore.clear != null) { this.sessionStore.clear(); resolve(`The sessions have been cleared!`); } else { reject(new Error(`Unable to clear sessions!`)); } }); }
我编写的测试代码如下(getError是获取错误的辅助方法,此处无关):
it('should throw an error when session clear is not available to be called', async () => { jest.spyOn(sessionStore, 'clear').mockImplementation(undefined) const result = await getError(() => adminSvc.clearAllSessions()); expect(sessionStore.clear).not.toHaveBeenCalled(); expect(result).toEqual(new Error(`Unable to clear sessions!`)); });
现在遇到的问题是:jest.spyOn会给sessionStore.clear创建一个模拟函数,而不是让它变成纯粹的undefined,导致业务代码走了成功分支,不符合测试预期。请问怎么正确模拟这个方法不存在的状态?
解决方案
不要用jest.spyOn,直接通过删除属性或赋值undefined的方式,让sessionStore.clear变成不存在的状态:
修改后的测试代码如下:
it('should throw an error when session clear is not available to be called', async () => { // 方法1:直接删除clear属性 delete sessionStore.clear; // 方法2:直接赋值为undefined // sessionStore.clear = undefined; const result = await getError(() => adminSvc.clearAllSessions()); expect(result).toEqual(new Error(`Unable to clear sessions!`)); });
原因说明
jest.spyOn的核心逻辑是创建一个模拟函数去覆盖原方法,哪怕你设置mockImplementation(undefined),sessionStore.clear依然是一个存在的模拟函数,所以业务代码里的if (this.sessionStore.clear != null)会判定为true,走成功分支。
只有直接删除该属性,或者把它赋值为undefined,才能让业务代码的判断条件触发false分支,进入错误处理逻辑,符合测试预期。
内容的提问来源于stack exchange,提问作者Chris Barr
相关产品推荐
相关产品推荐

