Typescript 如何在beforeach中模拟Knex(Knex)

Typescript 如何在beforeach中模拟Knex(Knex),typescript,mocking,jestjs,tdd,knex.js,Typescript,Mocking,Jestjs,Tdd,Knex.js,我绞尽脑汁试图理解如何模拟第三方库。我对TDD完全陌生,因此所有的信息现在对我来说都没有意义 我想测试我的类,如下所示: // my-class.test.ts import { MyClass } from './my-class'; describe('Testing my class', () => { let myClass: MyClass; beforeEach(() => { jest.mock('knex', () => jest.fn());

我绞尽脑汁试图理解如何模拟第三方库。我对TDD完全陌生,因此所有的信息现在对我来说都没有意义

我想测试我的类,如下所示:

// my-class.test.ts
import { MyClass } from './my-class';

describe('Testing my class', () => {
  let myClass: MyClass;
  beforeEach(() => {
    jest.mock('knex', () => jest.fn());
    const knex = import('knex').Knex;
    const transacting = jest.fn();
    const where = jest.fn(() => ({ transacting }));
    const from = jest.fn(() => ({ where }));
    const withSchema = jest.fn(() => ({ from }));
    const select = jest.fn(() => ({ withSchema }));
    knex.mockImplementation(() => ({select}));
    myClass = new MyClass(knex, ???)
  });
  test(("should return mocked value") => {
    // ???
  })
});
我想在
MyClass
中基本上测试这样一个方法:

// my-class.ts
export class MyClass {
  private knex: Knex;
  private transaction: Knex.Transaction;
constructor(knex: Knex, transaction: Knex.Transaction) {
  this.knex = knex;
  this.transaction = transaction;
}
async myMethod(id: string){
  return await this.knex
    .select('name')
    .withSchema('public')
    .from('table')
    .where({ id })
    .transacting(this.transaction)
} 
首先,Typescript不允许我执行
Knex.mockImplementation
。其次,我不知道如何告诉Jest最后一个链式函数(transacting)应该在不同的测试中返回不同的值


如何使用Jest实现这一点?

对于您的情况,最好使用依赖项注入将模拟对象传递到
MyClass
。因此,您不需要调用
jest.mock
来模拟
knex
模块

例如

my class.ts

从“Knex”导入Knex;
导出类MyClass{
私人议会:议会;
私人交易:Knex.transaction;
构造函数(knex:knex,事务:knex.transaction){
this.knex=knex;
this.transaction=交易;
}
异步myMethod(id:string){
回来,等着这个
.选择('名称')
.withSchema(“公共”)
.from('表')
.where({id})
.交易(本交易);
}
}
my class.test.ts

从“/MyClass”导入{MyClass};
从“Knex”进口Knex;
描述('63863647',()=>{
它('should pass',async()=>{
常量可链表=({
事务处理:jest.fn().mockResolvedValueOnce({id:'1',name:'a'}),
}作为未知)作为Knex.chaineableInterface;
常数mKnex=({
选择:jest.fn().mockReturnThis(),
withSchema:jest.fn().mockReturnThis(),
from:jest.fn().mockReturnThis(),
其中:jest.fn().mockReturnValueOnce(可链接),
}(未知)如Knex;
const mTransaction=({}未知)作为Knex.Transaction;
const myclass=新的myclass(mKnex,mTransaction);
const actual=await myclass.myMethod('1');
expect(实际).toEqual({id:'1',name:'a'});
expect(mKnex.select).toBeCalledWith('name');
期望(mKnex.withSchema)。与(‘public’)一起调用;
expect(mKnex.from).toBeCalledWith('table');
expect(mKnex.where).toBeCalledWith({id:'1'});
期望(可链接。交易)。通过(MTTransaction)调用;
});
});
单元测试结果和覆盖率报告:

通过src/stackoverflow/63863647/my-class.test.ts
63863647
✓ 应通过(7毫秒)
-------------|----------|----------|----------|----------|-------------------|
文件|%Stmts |%Branch |%Funcs |%Line |未覆盖行|s|
-------------|----------|----------|----------|----------|-------------------|
所有文件| 100 | 100 | 100 | 100 ||
my-class.ts | 100 | 100 | 100 | 100 ||
-------------|----------|----------|----------|----------|-------------------|
测试套件:1个通过,共1个
测试:1项通过,共1项
快照:共0个
时间:4.666秒,估计13秒