如何在Sinon中断言属性赋值与函数调用的执行顺序?
用Sinon验证对象属性赋值与函数调用的执行顺序
被测函数
function systemUnderTest(func, param) { param.firstProperty = !param.firstProperty; func(); param.secondProperty = !param.secondProperty; }
需求
需要验证以下执行顺序:
param.firstProperty的赋值操作早于func()的调用func()的调用早于param.secondProperty的赋值
已知Sinon的spy.calledBefore(anotherSpy)方法可用于断言调用顺序,但不清楚如何给对象字面量param的属性添加调用记录,使其支持该方法。
解决方案
核心思路是给param的目标属性添加setter类型的Spy,每次对属性执行赋值操作时,Spy会被触发并记录调用时间,之后就能和func的Spy一起用calledBefore做顺序断言。
方法一:手动用Object.defineProperty创建Spy Setter
const sinon = require('sinon'); describe('systemUnderTest 执行顺序验证', () => { it('属性赋值与函数调用顺序符合预期', () => { // 1. 创建func的Spy const funcSpy = sinon.spy(); // 2. 给param的属性创建Setter Spy const param = {}; const firstPropSetSpy = sinon.spy(); const secondPropSetSpy = sinon.spy(); // 给firstProperty设置带Spy的setter,同时提供默认getter避免赋值时取反出错 Object.defineProperty(param, 'firstProperty', { set: firstPropSetSpy, get: () => false }); Object.defineProperty(param, 'secondProperty', { set: secondPropSetSpy, get: () => false }); // 3. 执行被测函数 systemUnderTest(funcSpy, param); // 4. 断言顺序 sinon.assert.calledBefore(firstPropSetSpy, funcSpy); sinon.assert.calledBefore(funcSpy, secondPropSetSpy); }); });
方法二:用Sinon Stub简化Setter Spy创建
如果param本身已有初始属性值,可以直接用Sinon的stub快速替换为带Spy的访问器:
const sinon = require('sinon'); describe('systemUnderTest 执行顺序验证', () => { it('属性赋值与函数调用顺序符合预期', () => { // 1. 创建func的Spy const funcSpy = sinon.spy(); // 2. 初始化param并给属性创建Setter Spy const param = { firstProperty: false, secondProperty: false }; sinon.stub(param, 'firstProperty').set(sinon.spy()); sinon.stub(param, 'secondProperty').set(sinon.spy()); // 3. 执行被测函数 systemUnderTest(funcSpy, param); // 4. 断言顺序(通过stub的setter属性获取Spy) sinon.assert.calledBefore(param.firstProperty.setter, funcSpy); sinon.assert.calledBefore(funcSpy, param.secondProperty.setter); }); });
原理说明
对对象属性的赋值操作会触发属性的setter方法,我们用Sinon Spy替换原本的setter后,每次赋值都会让Spy记录一次调用。这样firstProperty的setter Spy、func Spy、secondProperty的setter Spy就都有了调用时间戳,通过calledBefore就能轻松验证三者的执行顺序。
内容的提问来源于stack exchange,提问作者Daniel Kaplan
相关产品推荐
相关产品推荐

