【问题标题】:Trying to access mockedFunction.mock.instaces property gives undefined in Jest尝试访问 mockedFunction.mock.instaces 属性在 Jest 中给出 undefined
【发布时间】:2019-05-07 05:51:54
【问题描述】:

我想模拟一个名为 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

【问题讨论】:

    标签: jestjs jest-fetch-mock


    【解决方案1】:

    当您使用new 运算符调用函数时,会创建一个新对象并将其作为执行上下文(又名this)传递给该函数。如果函数没有显式返回任何内容,则该对象将被隐式返回。你可以看看detailed explanation

    另外,请注意arrow function can never be used as a constructor

    来自mock functions 的 Jest 文档:

    mockFn.mock.instances

    一个数组,其中包含已使用 new 从此模拟函数实例化的所有对象实例。

    因此,每次调用时,Jest 模拟函数都会在 instances 属性中存储传递给函数的对象实例列表(作为 this 传递给函数的新创建的对象) new 运算符。

    但是你的构造函数没有使用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 attribute

    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");
    });
    

    【讨论】:

    • 几乎......只需将箭头功能更改为正常功能。箭头函数永远不能是构造函数,因为它没有自己的this(它总是使用定义它的范围的this
    • 你是绝对正确的。我编辑了答案以纠正它。谢谢!
    猜你喜欢
    • 2012-03-18
    • 1970-01-01
    • 2019-12-12
    • 2021-05-21
    • 1970-01-01
    • 2019-06-29
    • 2019-08-24
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多