Jasmine 中 and.stub 与 and.callFake 有什么区别

问题描述 投票:0回答:2

我是

Jasmine
的新手,对上述两个功能有点困惑。我的唯一目的是为间谍功能提供一个虚假的实现。但是,如果我将调试器放入
callFake
中,它会被调用,但
and.stub
的函数不会被调用。谁能解释一下这两个函数有什么区别。

spyOn(manager, 'getUsers').and.stub(function () {
    //to do
});

 spyOn(manager, 'getUsers').and.callFake(function () {
        //to do
    });
unit-testing jasmine karma-jasmine
2个回答
20
投票

查看位于 https://jasmine.github.io/2.0/introduction.html#section-Spies 的文档,当您

spyOn
时,它会记录对监视对象方法进行的所有调用。这意味着它正在调用对象的实际方法,但会跟踪进行了哪些调用。

如果您想允许使用原始对象,但不希望调用特定方法,您可以选择使用

and.callFake
and.stub
。差异在于方法签名。


callFake
将函数作为参数。这允许您伪造方法调用并返回您想要的值。

原始方法签名是

myMethod(param1: string): string

spyOn(service, 'myMethod').and.callFake((param1) => {
    expect(param1).toBe('value');
    return 'returnValue';
});

stub
没有参数,只是拦截对方法的调用

spyOn(service, 'myMethod').and.stub();

myMethod 可以有参数,也可以有返回类型,但这并不重要,因为存根只是拦截调用,如果有返回类型,就会返回

null


在这两种情况下,都会记录方法调用,然后您可以执行类似

expect(service.myMethod).toHaveBeenCalled()
expect(service.myMethod).toHaveBeenCalledWith('value')

的操作

0
投票

所以,

let mySpy = spyOn(service, 'myMethod').and.stub()
let mySpy = spyOn(service, 'myMethod')
完全相同。这两者都做同样的两件事:

1 - 他们会等到该函数被调用,并可以稍后报告并告诉您它是否是通过

expect(mySpy).toHaveBeenCalled()
调用的。

2 - 他们拦截该函数并且从不调用它。因此,如果您监视一个函数,它实际上不会被调用。与

let mySpy = spyOn(service, 'myMethod').and.returnValue(someUsefulReturnValue)
配对时非常有用。

但是,作为旁注,在某些情况下,您想要监视一个函数以查看它是否被调用,请编写一个它被调用的期望,但实际上允许它被调用,此时您将使用

let mySpy = spyOn(service, 'myMethod').and.callThrough()

然而,

let mySpy = spyOn(service, 'myMethod').and.callFake()
在上面的要点中做了同样的两件事,除了一个好处。您可以调用
callFake()
内部的函数,该函数将在
myMethod
内部执行。我发现这在遵循编程原则时并不是非常有用,并且很少使用。

let mySpy = spyOn(service, 'myMethod').and.callFake(() => { this.somethingThatNeedsToBeUpdated = somethingUseful; })

© www.soinside.com 2019 - 2024. All rights reserved.