sinon 库的 fake、spy、stub 和 mock 之间的区别( sinon fake vs spy vs stub vs mock )

Zia*_*nur 18 javascript mocha.js node.js sinon jestjs

我试图理解 sinon 库的 fake、spy、stub 和 mock 之间的区别,但无法清楚地理解它。

有人可以帮我了解一下吗?

Zia*_*nur 24

只是为了理解目的调用

FuncInfoCollector = 是一个函数,它记录所有调用的参数、返回值、this(context) 的值和抛出的异常(如果有)。(这个 FuncInfoCollector 是我给的虚拟名称,它不存在于 SINON lib 中)

Fake= FuncInfoCollector + 只能创建一个函数,不能包装被测系统中已经存在的函数

假是不可变的:一旦创建,行为就无法改变。

var fakeFunc = sinon.fake.returns('foo');
fakeFunc();

// have call count of fakeFunc ( It will show 1 here)
fakeFunc.callCount;   
Run Code Online (Sandbox Code Playgroud)

Spy= FuncInfoCollector + 可以创建 函数 +可以包装被测系统中已经存在的函数。

每当测试的目标是验证发生的事情时,间谍都是一个不错的选择。

// Can be passed as a callback to async func to verify whether callback is called or not?
const spyFunc = sinon.spy();

// Creates spy for ajax method of jQuery lib
sinon.spy(jQuery, "ajax");       

// will tell whether jQuery.ajax method called exactly once or not 
jQuery.ajax.calledOnce 
Run Code Online (Sandbox Code Playgroud)

Stub= spy + 它存根原始函数(可用于更改原始函数的行为)

var err = new Error('Ajax Error');

// So whenever jQuery.ajax method is called in a code it throws this Error
sinon.stub(jQuery, "ajax").throws(err) 

// Here we are writing assert to check where jQuery.ajax is throwing an Error or not
sinon.assert.threw(jQuery.ajax(), err);
Run Code Online (Sandbox Code Playgroud)

Mock =存根+预编程的期望

var mk = sinon.mock(jQuery)

// Should be called atleast 2 time and almost 5 times
mk.expects("ajax").atLeast(2).atMost(5); 

// It throws the following exception when called ( assert used above is not needed now )
mk.expects("ajax").throws(new Error('Ajax Error')) 

// will check whether all above expectations are met or not, hence assertions aren't needed
mk.verify(); 
Run Code Online (Sandbox Code Playgroud)

请也看看这个链接sinon.replace vs sinon.stub 只是为了替换返回值?

  • 刚刚编辑了说 Fake 不能替换现有函数的部分,因为这是不正确的。假货涵盖了存根的所有用例,包括替换现有方法。您只需要单独调用 sinon.replace :) (3认同)

oli*_*ren 11

只是为了向原本不错的答案添加更多信息,我们将 Fake API 添加到了 Sinon,因为其他原始 API(Stub 和 Spy)存在缺陷。事实上,这些 API 是可链式的,导致了持续的设计问题和反复出现的用户问题,而且它们为了满足相当不重要的用例而变得臃肿,这就是为什么我们选择创建一个新的不可变 API,它更易于使用、不那么模糊和维护成本更低。它构建在 Spy 和 Stub API 之上,让 Fakes 具有一定的可识别性,并具有替换对象上的 props 的显式方法 ( sinon.replace(obj,'prop',fake))。

假货本质上可以在任何可以使用存根或间谍的地方使用,所以我自己已经有 3-4 年没有使用过旧的 API,因为使用更有限的假货的代码对其他人来说更容易理解。