为什么jest v24模拟类需要私有方法

时间:2019-02-13 22:15:26

标签: typescript visual-studio-code jestjs

我需要使用jest v24 +创建我的打字稿类的模拟实现。我专门尝试创建一个模拟类,该类被注入到构造函数中,并模拟将被调用以返回特定响应的函数。

如何为每个测试创建模拟?

更多信息:

我已经开始了一个新项目,现在使用的是jest v24,这在编写无法解决的测试方面造成了问题。

使用下面带有jest v23的示例,以前我可以按如下方式模拟Randomiser类:

const Mock = jest.fn<Randomiser>(() => ({
  getRandom: jest.fn().mockReturnValue(10)
}));

将成功编译并构建。

从v24开始,fn函数采用了附加的泛型<T, Y extends any[]>,我不知道这是否与行为改变有关,但是现在我得到了一个错误:

类型'{getRandom:Mock;中缺少属性'rand' }”,但类型为“ Randomiser”。ts(2741)

import "jest";

class Randomiser {
    public getRandom(): number {
        return this.rand();
    }
    private rand(): number {
        return Math.random();
    }
}

class Multiplier {
    private randomiser: Randomiser;
    constructor(randomiser: Randomiser) {
        this.randomiser = randomiser;
    }

    multiplyRandom(factor: number): number {
        return Math.floor(this.randomiser.getRandom() * factor);
    }
}

describe("tests", () => {
    it("10 x 2 = 20", () => {
        const Mock = jest.fn<Randomiser, any>(() => ({
            getRandom: jest.fn().mockReturnValue(10),
            rand: jest.fn() //with this line I get an error because it should be private, without this line I get the error above.
        }));
        expect(new Multiplier(new Mock()).multiplyRandom(2)).toBe(20);
    })
})

我希望能够以与v23相同的方式编写模拟,即可以模拟类,而只需要模拟要调用的函数。

现在,我必须模拟所有函数,包括私有函数和私有属性,然后抱怨它们不是私有的。

1 个答案:

答案 0 :(得分:1)

两种解决方案:

1。使用Partial<Type>,这将允许您部分模拟您的班级:

const Mock = jest.fn<Partial<Randomiser>, []>(() => ({
  getRandom: jest.fn().mockReturnValue(10)
}));

然后将您的模拟对象转换为您的类类型以注入它,例如:

const mock: Randomiser = new Mock() as Randomiser;
expect(new Multiplier(mock).multiplyRandom(2)).toBe(20);

2。不要为模拟指定任何类型。

另一种方法是不指定模拟的类型,这将使​​模拟类型为any

const Mock = jest.fn(() => ({
  getRandom: jest.fn().mockReturnValue(10)
}));

然后,您可以直接注入模拟,但在这种情况下当然不会输入。

const mock = new Mock();
expect(new Multiplier(mock).multiplyRandom(2)).toBe(20);