我有一个难题,试图让手动模拟使用一些本地代码。基本上有一个与异步资源交互的组件(在本例中为lowdb
)。现在我可以从lowdb
模拟我正在使用的所有函数,但是这个函数的输出实际上非常简单,我宁愿只是模拟那个调用。但是,我正在构建的测试不会直接调用此函数。
这可能不太清楚,所以这里有一个例子(这是我想要模拟的方法):
export const getNextId = (): Promise<number> => {
return new Promise<number>((resolve, reject) => {
// not the actual call, but akin to it
getDB().then((db: LowdbAsync<Schema>) => {
resolve(db.get('count').value()) as number
}
}
然后在不同的文件中,我使用它来设置ID(这用于某些I / O)。
import { getNextId } from '../../db'
export interface Job {
id: number
}
export class Job implements Job {
constructor(public id: number) { }
}
export const getNewJob = (): Promise<Job> => {
return new Promise<Job>((resolve, reject) => {
getNextId().then((id: number) => {
resolve(new Job(id))
}
}
}
就像那样丑陋,这就是所需要的。
因此,在我的测试文件中,我有一行代码可以创建一个新的Job
。我可以通过修改构造函数来思考如何解决这个问题,但我宁愿这样做惯用。
到目前为止,这是最接近的我已经得到了它的工作。这只是防止它在运行时爆炸(测试,即),但它实际上并没有调用我的手动模拟函数。
看哪:
const db = jest.createMockFromModule('../../db')
// this is ugly but i'm using TS on strict
db['getNextId'] = (): Promise<number> => {
return new Promise<number>((resolve, reject) => {
resolve(0)
}
}
import { someUtilMethod } from '../../app/util'
import { Job, getNewJob } from '../../app/job'
describe('foo', () => {
getNewJob().then((job: Job) => {
let testVal: string = someUtilMethod(job)
// then assert some value here
}
}
虽然开始模仿本地模块似乎确实让它运行(没有getNextId
未定义的问题)但它实际上从未调用我的手动模拟函数。我尝试了一些方法,这是至少让测试运行的唯一方法...但是{永远不会设置id
值并且日志/调试验证手动模拟功能从未被击中。
我可以很容易地做一些愚蠢的事情,但是从我读过的所有应该工作。我甚至尝试了基本的非Promise
基本调用(这显然不是我的问题),并且调用方法来获取辅助方法之外的ID(例如在测试中)都无济于事。在jest
加载模块的过程中,我遗漏了一些东西。
答案 0 :(得分:0)
Havent尝试使用jest.createMockFromModule
。我喜欢使用jest.spyOn
参见jest docs' example,它可以模拟模块的特定功能,并且可以在每个测试中完成(即使用mockRestore()
将功能恢复为正常)。
顺便说一句,我还在it
内添加了describe
以使其正常运行,并在await
中添加了要解决的测试。
测试:
import * as db from '../src/db';
import { Job, getNewJob } from '../src/stackoverflow2';
// import { someUtilMethod } from '../../app/util'
const someUtilMethod = (job: Job) => JSON.stringify(job);
describe('foo', () => {
it('bar', async () => {
const getNextIdSpy = jest.spyOn(db, 'getNextId');
getNextIdSpy.mockResolvedValue(5);
await getNewJob().then((job: Job) => {
let testVal: string = someUtilMethod(job);
// then assert some value here
expect(testVal).toBe('{"id":5}');
});
getNextIdSpy.mockRestore();
});
});