【发布时间】:2020-10-21 20:01:13
【问题描述】:
我试图理解 sinon 库的 fake、spy、stub 和 mock 之间的区别,但无法清楚地理解。
谁能帮我理解一下?
【问题讨论】:
标签: javascript node.js jestjs mocha.js sinon
我试图理解 sinon 库的 fake、spy、stub 和 mock 之间的区别,但无法清楚地理解。
谁能帮我理解一下?
【问题讨论】:
标签: javascript node.js jestjs mocha.js sinon
只是为了理解目的调用:
FuncInfoCollector = 是一个函数,它记录所有调用的参数、返回值、this(context) 的值和抛出的异常(如果有的话)。 (这个 FuncInfoCollector 是我给的假名,它不存在于 SINO lib 中)
Fake = FuncInfoCollector + 只能创建一个fake函数,它不能包装一个已经存在在系统中的函数正在测试中。
虚假是不可变的:一旦创建,行为就无法更改。
var fakeFunc = sinon.fake.returns('foo');
fakeFunc();
// have call count of fakeFunc ( It will show 1 here)
fakeFunc.callCount;
Spy = FuncInfoCollector + 可以创建 新函数 + 它可以包装一个已经存在于被测系统中的函数。
当测试的目标是验证某事发生时,Spy 是一个不错的选择。
// 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
Stub = spy + it stubs 原始函数(可用于改变原始函数的行为)。
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);
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();
也请查看此链接sinon.replace vs sinon.stub just to replace return value?
【讨论】:
只是为了给原本不错的答案添加更多信息,我们将 Fake API 添加到 Sinon,因为其他原始 API(Stub 和 Spy)的缺点。这些 API 可链接的事实导致了不断的设计问题和反复出现的用户问题,并且它们过于臃肿以迎合相当不重要的用例,这就是为什么我们选择创建一个新的不可变 API,它更易于使用、更少歧义和维护成本更低。它建立在 Spy 和 Stub API 之上,让 Fakes 具有一定的可识别性,并有明确的方法来替换对象上的 props (sinon.replace(obj,'prop',fake))。
Fakes 基本上可以在任何可以使用 stub 或 spy 的地方使用,因此我自己已经 3-4 年没有使用过旧的 API,因为使用更有限的 fakes 的代码对其他人来说更容易理解。
【讨论】: