我想模拟一个名为dog
的构造函数Dog = jest.fn(()=>{
return{
name:"spike",
bark:function(){
return "bhow " +this.name;
}
}
})
function foo(){
const d = new Dog();
return d.bark();
}
test("testing foo",()=>{
const result = foo();
expect(Dog).toHaveBeenCalledTimes(1);
expect(result).toBe("bhow spike");
expect(Dog.mock.instances.length).toBe(1);
expect(Dog.mock.instances[0].name).toBe("spike");
//this test failed with expected spike received undefined
});
但是expect(Dog.mock.instances[0].name).toBe("spike");
预期尖峰的失败未定义
开玩笑版本24.8.0节点版10.15.0
使用new
操作员调用函数时,将创建一个新对象并将其传递为执行上下文(aka this
(。如果该函数没有明确返回任何内容,则将隐式返回该对象。您可以查看详细说明。
另外,考虑到箭头功能永远无法用作构造函数。
来自模拟功能的Jest文档:
MOCKFN.MOCK.INSTANCE
一个包含使用新模拟函数实例化的对象实例的数组。
因此,每次使用new
运算符调用它时,JEST模拟函数都存储在instances
中的 CC_4属性归因于要传递给函数的对象实例列表(新创建的对象(新创建的对象((。
但是您的构造函数不使用this
对象,因此它保持空。这就是为什么当您检查Dog.mock.instances[0].name
时,您将获得undefined
。如果将构造函数稍有更改以将 name 属性分配给this
对象,则可以看到您的测试通过:
Dog = jest.fn(function() {
this.name = "spike";
return{
name:"spike",
bark:function(){
return "bhow " +this.name;
}
}
})
很少使用从构造函数函数中明确返回对象。定义构造函数的最常见方法是将其属性分配给this
对象。因此,解决问题的方法是将构造函数更改为:
Dog = jest.fn(function() {
this.name = "spike";
this.bark = function(){
return "bhow " +this.name;
}
})
另一个解决方案,如果您不想更改构造函数函数的定义,则是在测试中使用模拟函数的results
属性:
test("testing foo",()=>{
const result = foo();
expect(Dog).toHaveBeenCalledTimes(1);
expect(result).toBe("bhow spike");
expect(Dog.mock.instances.length).toBe(1);
expect(Dog.mock.results[0].value.name).toBe("spike");
});