https://sinonjs.org/releases/v7.5.0/spies/

spy 什么是测试间谍?

测试谍照是记录参数,返回值的值的函数 this,并抛出异常(如果有的话)的所有来电。间谍有两种类型:一些是匿名函数,而其他一些则包装被测系统中已经存在的方法。

  1. var assert = require("assert");
  2. var sinon = require("sinon");
  3. var { fake, spy } = sinon;
  4. debugger;
  5. // 首先是一般设置
  6. describe('My test suite', () => {
  7. afterEach(() => {
  8. // Restore the default sandbox here
  9. sinon.restore();
  10. });
  11. });
  12. // 然后是 Spies
  13. var spy = sinon.spy(); // 使用spy创建匿名函数。间谍除了记录有关其通话(执行次数等)的信息外什么都不会做。
  14. var obj = {
  15. methodA: function () {
  16. console.log(this.name);
  17. }
  18. };
  19. var obj2 = {
  20. methodA: function () {
  21. console.log(this.name);
  22. }
  23. };
  24. var fn2 = obj2.methodA;
  25. var fn1 = function () { }
  26. var callback2 = sinon.spy(obj); // 监视对象的所有方法。通常不建议这样做
  27. var callback3 = sinon.spy(obj2, "methodA"); // 监听一个特定的函数
  28. var callback4 = sinon.spy(fn1); // 监听一个特定的函数
  29. var isSourceAndTargetA = obj.methodA === callback2.methodA; // true
  30. callback2.methodA.restore() // 用原始方法替换间谍。仅当间谍替换了现有方法时可用。
  31. var isSourceAndTargetB = obj.methodA === callback2.methodA; // true
  32. var isSourceAndTargetC = obj2.methodA === callback3.methodA; // false
  33. var isSourceAndTargetD = fn2 === obj2.methodA; // false
  34. obj2.methodA.restore() // 可以通过调用恢复原始方法 object.method.restore() 恢复原始方法
  35. var isSourceAndTargetE = fn2 === obj2.methodA; // true
  36. var isSourceAndTargetF = obj2.methodA === callback3.methodA; // false
  37. var isBool = spy.calledOnce; // false
  38. spy(); // 如果他刚刚被执行了一次
  39. isBool = spy.calledOnce; // true
  40. spy("aaa");
  41. isBool = spy.calledTwice; // true 如果他刚刚被执行了两次返回true
  42. isBool = spy.calledWith("aaa"); // true 如果曾经使用提供的参数调用过间谍,它将返回true
  43. isBool = spy.calledWith("bbb"); // false
  44. spy("bbb");
  45. isBool = spy.calledThrice; // true 如果他刚刚被执行了三次返回true
  46. isBool = spy.calledWith("aaa"); // true 如果曾经使用提供的参数调用过间谍,它将返回true
  47. isBool = spy.calledWith("bbb"); // true
  48. var args = spy.args[0][0]; // 第一次调用的,第一个参数
  49. args = spy.args[1][0]; // 第二次调用的,第一个参数
  50. args = spy.args[2][0]; // 第三次调用的,第一个参数
  51. var spyCall = spy.getCall(0); // spy.getCall(0); 返回第一次调用 当间谍被多次呼叫时,访问单个呼叫有助于进行更详细的行为验证。
  52. spyCall = spy.getCall(1); // spy.getCall(1); 返回第二次调用
  53. // 间谍对象是从返回的对象sinon.spy()。
  54. // 当使用监视现有方法时sinon.spy(object, method),还可使用以下属性和方法object.method
  55. var count = spy.callCount; // 3 记录被执行次数
  56. isBool = spy.called // true 至少被执行一次
  57. isBool = spy.notCalled; // false 从没有被执行过的话返回true
  58. isBool = spy.getCall(0) === spy.firstCall // false 虽然返回fasle 但是他也是获取第一次调用 第一次电话
  59. isBool = spy.getCall(1) === spy.secondCall // 第二次通话 虽然返回fasle 但是他也是获取第二次调用
  60. isBool = spy.getCall(2) === spy.thirdCall // 第三次通话 虽然返回fasle 但是他也是获取第三次调用
  61. isBool = spy.getCall(2) === spy.lastCall // 最后一个电话 虽然返回fasle 但是他也是获取第三次调用
  62. var spyCalls = spy.getCalls(); // 返回被调用次数组
  63. callback4();
  64. isBool = spy.calledBefore(callback4); // true 是否在callback4之前被调用过,如果调用过是返回tur,否在返回false
  65. isBool = spy.calledAfter(callback4); // false 是否在callback4之后被调用过,是返回true,否在返回false
  66. isBool = spy.calledImmediatelyBefore(callback4); // true spycallback4之前调用,并且没有在between spy and callback4被调用,符合条件返回true,否则返回false
  67. spy();
  68. isBool = spy.calledImmediatelyBefore(callback4); // false
  69. isBool = spy.calledImmediatelyAfter(callback4); // true spycallback4之后调用,并且没有在between spy and callback4被调用,符合条件返回true,否则返回false
  70. callback4();
  71. isBool = spy.calledImmediatelyAfter(callback4); // false
  72. describe("xxxx", function () {
  73. var object = { method: function () { } };
  74. var spy1 = sinon.spy(object, "method");
  75. object.method(42);
  76. object.method(1);
  77. // spy.withArgs(arg1[, arg2, ...]); 创建一个间谍,仅在接收到的参数与传递给的参数匹配时记录
  78. assert(spy1.withArgs(42).calledOnce); // 通过
  79. assert(spy1.withArgs(1).calledOnce); // 通过
  80. })
  81. // this对象数组,spy.thisValues[0]是this第一个调用的对象。
  82. var self = spy.thisValues // [undefined,undefined,undefined,undefined]
  83. var obj = {};
  84. spy.apply(obj, []);
  85. self = spy.thisValues // [undefined,undefined,undefined,undefined, obj]
  86. var values = spy.returnValues; // 调用函数的返回值数组
  87. var ex = spy.exceptions; // 异常 引发的异常对象数组spy.exceptions[0]是第一次调用引发的异常。如果呼叫没有引发错误,则呼叫位置中的值.exceptions将为undefined
  88. spy.threw(); // true如果间谍至少引发一次异常,则返回。
  89. spy.threw("TypeError"); // true如果spy至少抛出一次所提供类型的异常,则返回。
  90. spy.threw(obj); // 返回:true如果间谍至少一次抛出了提供的异常对象。
  91. spy.alwaysThrew(); // true如果间谍总是抛出异常,则返回。
  92. spy.alwaysThrew("TypeError"); // true如果spy总是抛出所提供类型的异常,则返回。
  93. spy.alwaysThrew(obj); // 返回:true如果间谍总是抛出所提供的异常对象。
  94. spy.returned(obj); // 返回true如果间谍返回至少提供一次价值。
  95. // 对对象和数组使用深度比较。用spy.returned(sinon.match.same(obj))严格的比较(见的匹配)。
  96. spy.alwaysReturned(obj); // 返回true如果间谍总是返回所提供的价值。
  97. // 验证this
  98. spy.calledOn(obj); // 返回true是否使用obj 至少调用过一次间谍thiscalledOn也接受匹配器spyCall.calledOn(sinon.match(fn))(请参阅matchers)。
  99. spy.alwaysCalledOn(obj); // 返回true是否始终以objas 调用间谍this
  100. spy.calledOnceWith(/*arg1, arg2, ...*/); // 返回true是否总共总共只对spy调用一次,并且一次调用使用的是提供的参数。
  101. spy.alwaysCalledWith(/*arg1, arg2, ...*/); // 返回true是否始终使用提供的参数(可能还有其他参数)调用spy
  102. spy.calledWithExactly(/*arg1, arg2, ...*/); // 返回true是否使用提供的参数调用了间谍至少一次,没有其他调用。
  103. spy.calledOnceWithExactly(/*arg1, arg2, ...*/); // 返回true是否总共总共只对spy调用一次,并且一次调用使用的是提供的确切参数,而没有其他调用。
  104. spy.alwaysCalledWithExactly(/*arg1, arg2, ...*/); // 返回true是否始终使用提供的确切参数调用spy
  105. spy.calledWithMatch(/*arg1, arg2, ...*/); // true是否使用匹配的参数(可能还有其他参数)调用了间谍。行为与相同spy.calledWith(sinon.match(arg1), sinon.match(arg2), ...)。
  106. spy.alwaysCalledWithMatch(/*arg1, arg2, ...*/); // 返回true是否始终使用匹配的参数(可能还有其他参数)调用spy。行为与相同spy.alwaysCalledWith(sinon.match(arg1), sinon.match(arg2), ...)。
  107. spy.neverCalledWith(/*arg1, arg2, ...*/); // 返回true是否从未使用提供的参数调用间谍/存根。
  108. spy.neverCalledWithMatch(/*arg1, arg2, ...*/); // 返回true是否从未使用匹配的参数调用间谍/存根。行为与相同spy.neverCalledWith(sinon.match(arg1), sinon.match(arg2), ...)。
  109. spy.calledWithNew(); // 返回true是否将spy / stub称为new运算符。请注意,这是根据this对象的值和spy函数的推断的prototype,因此,如果您主动返回正确的对象类型,则可能会产生误报。
  110. /*
  111. spy.printf("format string", [arg1, arg2, ...]);
  112. 返回传递的格式字符串,并执行以下替换:
  113. %n
  114. 间谍的名称“间谍”(默认情况下)
  115. %c
  116. 间谍被调用的次数,以单词(“一次”,“两次”等)表示
  117. %C
  118. 间谍程序调用的字符串表示形式的列表,每个调用以换行符和四个空格为前缀
  119. %t
  120. 以逗号分隔的this值列表,调用间谍
  121. %n
  122. 传递给的第n个参数的格式值printf
  123. %*
  124. 传递给(非格式字符串)参数的逗号分隔列表 printf
  125. %D
  126. 由所有对间谍的调用接收到的参数的多行列表
  127. */
  128. var str = spy.printf("format string: %c | %n", [spy.callCount, spy.name]);
  129. spy.resetHistory(); // 重置间谍的状态
  130. isBool = spy.called; // false