Javascript 在不运行构造函数的情况下初始化类以使用jest测试其他方法

Javascript 在不运行构造函数的情况下初始化类以使用jest测试其他方法,javascript,ecmascript-6,jestjs,Javascript,Ecmascript 6,Jestjs,我有一个类,当一个新实例初始化时,它调用一个私有验证方法,但是我想单独测试验证方法。下面是一个简单的人为的例子。。。可能有一种方法可以重构代码或api来避免这种情况,但解决它以更好地理解jest却成了一个挑战。这可能吗 class-Foo{ 构造函数(){ 这个.bar() } bar(){ 返回“bar” } } 描述('bar',()=>{ 让福 让酒吧 在每个之前(()=>{ //在这里模拟构造函数 Foo.prototype.bar=jest.fn() foo=新foo() }) 它('

我有一个类,当一个新实例初始化时,它调用一个私有验证方法,但是我想单独测试验证方法。下面是一个简单的人为的例子。。。可能有一种方法可以重构代码或api来避免这种情况,但解决它以更好地理解jest却成了一个挑战。这可能吗

class-Foo{
构造函数(){
这个.bar()
}
bar(){
返回“bar”
}
}
描述('bar',()=>{
让福
让酒吧
在每个之前(()=>{
//在这里模拟构造函数
Foo.prototype.bar=jest.fn()
foo=新foo()
})
它('应该调用一次',()=>{
foo.bar()
期望(foo.bar).toBeCalledTimes(1)
})
})

您可以使用相同的原型创建对象,而无需像这样运行构造函数:

const obj = Object.create(Foo.prototype);
使用您提供的原型创建对象
Foo.prototype
是分配给通过
new Foo
创建的对象的原型,因此这做同样的事情,但不运行构造函数代码
obj
将具有所有的
Foo
原型方法(
bar
等),并且
obj instanceof Foo
将为true,但它不会运行构造函数

例如:

class-Foo{
构造函数(){

console.log(“Constructor ran”);//您可以尝试使用
jest.spyOn
方法监视对象方法,如下所示:

description('bar',()=>{
让福
让酒吧
在每个之前(()=>{
const foo=Object.create(foo.prototype);//TJ Crowder建议
//Spy对象foo,侦听对方法栏的调用并模拟返回
jest.spyOn(foo,'bar').mock实现(()=>/*自定义返回*/);
foo.bar();
})
它('应该调用一次',()=>{
foo.bar()
期望(foo.bar).toBeCalledTimes(1)
})
})

可以模拟私有方法进行测试,这可以被视为反射-除非这些是当前无法反射的本机私有成员

在JavaScript中,构造函数本身就是一个类,因此模仿构造函数没有多大意义。依赖原型链的继承类的方法可以使用
对象进行测试。创建
,就像其他答案所示。没有继承的类或对象的方法可以通过使用特定上下文调用来测试:

// test the class
jest.spyOn(Foo.prototype, 'bar').mockReturnValue(...);
let foo = new Foo();
...
Foo.prototype.bar.mockRestore();

// test the method separately
let fooCtx = {};    
expect(Foo.prototype.bar.call(fooCtx, ...)).toEqual(...);
expect(fooCtx).toEqual({...});

bar()
不是静态的,因此在不先创建实例的情况下无法调用它。您不能“初始化”一个类。@ChrisG-你可以创建带有任意原型的对象,包括使用
Foo.prototype
:-)作为一个在我职业生涯早期编写过很多类似测试的人,我想你会后悔对这样的事情大肆嘲弄。最好创建实例并检查
bar
应该做的任何事情是否已经完成,而不是验证是否调用了
bar