使用 Sinon.js 可以轻松验证函数被调用时的参数,通过其提供的断言方法和调用信息对象,可以精确检查函数调用时传递的参数是否符合预期。 以下是具体的实现方法和示例:核心方法与属性Sinon 提供了多种方式验证函数调用参数,常用的包括:方法/属性 说明 () 进行部分匹配或类型匹配: // 验证参数包含某个属性 expect(spy.calledWith(sinon.match({ id: 123 }))).to.be.true; / / 验证参数类型 expect(spy.calledWith(sinon.match.number, sinon.match.string)).to.be.true;异步函数的参数验证对于异步函数, 需要等待 Promise 完成后再验证参数(如示例中的 await new Promise(...))总结使用 Sinon.js 验证函数调用参数的核心流程是:用 sinon.stub() 或 sinon.spy
在使用 Sinon.js 时,可以通过 called、calledOnce、calledTwice 等属性或 calledWithExactly()、callCount 等方法来验证函数的调用次数,从而设置和检查期望的调用次数 以下是具体的实现方法和示例:核心方法与属性Sinon 提供了多种方式来检查函数的调用次数,常用的包括:方法/属性 说明 (logSpy, 2); // 验证第二次调用的参数 sinon.assert.calledWithExactly(logSpy.secondCall, 'error');});常用的调用顺序相关方法 :firstCall:第一次调用的信息secondCall:第二次调用的信息thirdCall:第三次调用的信息lastCall:最后一次调用的信息总结使用 Sinon.js 验证函数调用次数的核心步骤是 :用 sinon.spy() 或 sinon.stub() 创建监视函数(spy/stub);执行触发函数调用的操作;通过 calledOnce/callCount 等属性或 sinon.assert.callCount
官网:www.chaijs.com/ github: github.com/chaijs/chai assert库方法文档: www.chaijs.com/api/assert/… sinon.js sinon 主要用来mock一些东西,比如可以用sinon mock一个假的函数,sinon也可以返回这个函数执行与否。 再执行以下安装语句: npm install sinon moncha chai sinon-chai --save-dev 复制代码 建立一个test文件夹,可以把写测试用例的Js放在这个文件夹中, 和 chai,要使用到sinon-chai const chai = require("chai") const sinon = require("sinon") const sinonChai = 模拟函数 如果需要模拟一个函数,可以用sinon去模拟,使用方法:sinon.fake(),并且课已通过这个sinon的called方法判断函数是否被执行。
通过本文,你可以解决以下问题: Jest与Sinon.js是什么? 如何配置Jest与Sinon.js,从而编写单元测试? 如何解决进行单元测试中遇到的常见问题? Sinon.js配置 依赖包安装 安装配置完了Jest,让我们来看下Sinon.js。 需要使用Sinon.js,我们首先需要进行安装: npm install sinon -D 配置完成后,需要在使用的地方进行引入,如下所示: const sinon = require('sinon') 在Sinon.js的文档中,有专门关于XMLHttpRequest对象的模拟的章节,在下一章中,我们将会针对项目中sinon.js的使用进行简单的介绍。 正好Sinon.js能够做到这一点。
Sinon.js特点:专注于提供独立的测试工具(包括 Mock、Stub、Spy 等),可与任何测试框架(如 Mocha、Jasmine)配合使用。 核心功能: 模拟函数(sinon.stub()) 监视函数调用(sinon.spy()) 模拟定时器和 XHR 请求 示例:模拟 API 调用import sinon from 'sinon'; describe('useFetch', () => { let fetchStub; beforeEach(() => { // 创建 fetch 的 stub fetchStub = sinon.stub Jest Mock 与 Jest 深度集成,配置简单 依赖 Jest 环境,灵活性有限 Jest 单元测试 Sinon.js 多框架兼容:选择 Sinon.js(支持 Mocha、Jasmine 等)。 简单场景:直接使用测试框架内置的 Mock 功能(如 Jest、Vitest 的 Mock)。
基本上目前前端单元测试就在这两个库之间选了,下面是这两个库的区别,大家可以根据自己的需求进行选择: mocha: 优点: 终端显示友好 灵活,扩展性好 缺点: 自身集成度不高(没有断言,spy,异步等),而且经常要配合Chai,Sinon 两者功能覆盖范围粗略可以表示为: Jasmine(2.x) === Mocha + Chai + Sinon - mockserver PS: 个人实际使用后觉得Chai和Sinon毕竟是专门做特定功能的框架 ,用 Mocha + Chai + Sinon 这种方式会想对舒爽一点。 which-javascript-test-library-should-you-use-qunit-vs-jasmine-vs-mocha/ http://thejsguy.com/2015/01/12/jasmine-vs-mocha-chai-and-sinon.html
测试辅助工具 Sinon Sinon 是一个独立的 JavaScript 测试 spy, stub, mock库,没有依赖任何单元测试框架工程。 API 介绍 辅助工具库 Sinon 主要有三个Api:spy, stub, mock spy 翻译过来的意思是 “监视”。 sinon.js 中 spy 主要用来监视函数的调用情况,sinon 对待监视的函数进行 wrap 包装,因此可以通过它清楚的知道,该函数被调用过几次,传入什么参数返回什么结果,甚至是抛出的异常情况。 var spy = sinon.spy(orginObj, 'launch'); spy.restore(); 当 spy 使用完成后,切记把它恢复成原始函数,就像上边例子中最后一步那样。 如果你曾经听过“mock 对象”这种说法,这其实是一码事 —— Sinon 的 mock 可以用来替换整个对象以改变其行为,就像函数 stub 一样。
基本上目前前端单元测试就在这两个库之间选了,下面是这两个库的区别,大家可以根据自己的需求进行选择: mocha: 优点: 终端显示友好 灵活,扩展性好 缺点: 自身集成度不高(没有断言,spy,异步等),而且经常要配合Chai,Sinon 两者功能覆盖范围粗略可以表示为: Jasmine(2.x) === Mocha + Chai + Sinon - mockserver PS: 个人实际使用后觉得Chai和Sinon毕竟是专门做特定功能的框架 ,用 Mocha + Chai + Sinon 这种方式会想对舒爽一点。 which-javascript-test-library-should-you-use-qunit-vs-jasmine-vs-mocha/ http://thejsguy.com/2015/01/12/jasmine-vs-mocha-chai-and-sinon.html
from 'sinon'; global.expect = expect; global.sinon = sinon; 然后把它包括到 npm 脚本的运行套件中,并通过 --require . /test/test_helper.js --recursive", 我也添加了 sinon,因此它也可以全局可用。 现在无论什么时候,我们在写一个新的测试时,都不需要手动引入 expect 和 sinon。 ': 'sinon/pkg/sinon' } }, module: { // don't run babel-loader through the sinon module noParse: [ /node_modules\/sinon\// ], // run babel loader
这时候就需要引入sinon来帮助我们替换掉这些难以模拟的逻辑。 sinon库提供了三种功能:spies、stub和mock。 spies作为sinon最简单的功能,它不会对被监听函数的执行过程造成任何影响,stub和mock功能都是基于spies实现的。 /util'; it('call example function once', function(){ const spyGetTime = sinon.spy(util, 'getTime') it('测试格式化函数', function(){ const stub = sinon.stub(db, 'query').returns({data: []}) const res = db.query 我们也可以让替换函数主动抛出错误,来测试调用它的函数是否可以正确处理异常: it('测试db操作失败', async function(){ const stub = sinon.stub(db,
单元测试部分介绍 先讲一下用到了哪些测试框架和工具,主要内容包括: jest ,测试框架 enzyme ,专测 react ui 层 sinon ,具有独立的 fakes、spies、stubs、mocks payload) { return fetcher.postJSON('/api/biz/get-table', payload); } 业务代码很简单,那么测试用例也很简单: import sinon from 'sinon'; import { fetcher } from '@/utils/fetcher'; import * as api from '@/services/bizApi'; (), updateParams: sinon.fake() }; let defaultWrapper; beforeEach(() => { ({paging: {current: 2, pageSize: 25}}); }); }); 得益于设计分层的合理性,我们很容易利用构造 props 来达到测试目的,结合 enzyme 和 sinon
可以使用sinon来解决这个问题window.onbeforeunload = sinon.spy();但是如果,你需要在一个模块的测试用例跑完之后,刷新页面进行下一个测试用例,就不用使用这种方法,这时需要屏蔽代码中的刷新页面逻辑
13": "^1.0.3", "jest": "^22.1.4", "jquery": "^3.1.1", "regenerator-runtime": "^0.11.1", "sinon Backbone 中的请求,包括 Backbone.sync / model.fetch() 等, 本质上还是调用的 jQuery 中的 $.ajax 方法(默认情况下),也就是传统的 xhr 方式,使用 sinon $el.find('.multi').length).toEqual(0); }); 对方法调用的测试 自然还是用 sinon 来做: it('应正确响应事件回调并加载子模板', function() { //模拟的返回数据 const server = sinon.createFakeServer(); server.respondImmediately = true; //立即返回 (); const spy2 = sinon.spy(); const ViewClass1 = CardPrivileges({ data:{ title
Controls> 组件: import assert from 'assert'; import { shallow } from 'enzyme'; import { spy } from 'sinon , function() { it('should execute callback on buttons click', function() { const increase = sinon.spy (); const descrease = sinon.spy(); const wrapper = shallow( <Controls onIncrease={increase
目前,有许许多多的测试框架都提供了模拟HTTP请求相关的一些流程功能,我们在这边文章中将会讲到的,就是我们在上一篇关于单元测试的博客提高代码质量——使用Jest和Sinon给已有的代码添加单元测试中提到的 Sinon中引用的HTTP模拟框架nise。 它是Sinon.js的一部分,用来处理HTTP相关测试问题。 该库提供了替换原生的XHR对象和Server相关的接口,但是我们在本文中只介绍关于XHR部分,也就是浏览器中的XHR对象的替换。 附录 Sinon.js nise 我folk的nise
但在大型项目中,有些人用Sinon。两个库的哲学有点不同。 Jest的风格:自动化Mock Jest会在模块加载时自动处理mock。你在测试文件顶部写 jest.mock('. Sinon的风格:手动控制 Sinon是独立的库,不依赖特定的测试框架。 它给你更多的控制权: import sinon from'sinon'; const obj = { greet(name) { return`你好,${name}`; } }; / / 创建stub(Sinon的术语,类似Mock) const stub = sinon.stub(obj, 'greet').returns('Hi!') —— 完全被替换了 stub.restore(); // 清理 Sinon还有一个强大的特性叫做Stub,它比Jest的Mock更灵活: const stub = sinon.stub(obj,
在运行时更改实现称为 mocking,我们将使用 Sinon[7] 这一 mocking 框架来实现。 import chai from 'chai'; import sinon from 'sinon'; import sinonChai from 'sinon-chai'; chai.use(sinonChai ); it('should set info coming from endpoint', async () => { const commit = sinon.stub(); sinon.stub https://vue-test-utils.vuejs.org/ [5] Chai: https://chaijs.com/ [6] Vuex: https://vuex.vuejs.org/ [7] Sinon
var spy = sinon.spy(MyComp.prototype, 'componentDidMount');...expect(spy.callCount).toEqual(1); stub var myObj = { prop: function() { return 'foo'; } };sinon.stub(myObj, 'prop').callsFake(function isDisabled={true} /> ); expect( wrapper.find('input').exists() ).toBeTruthy(); }); }); sinon 其实图中的故事正是人所皆知的“特洛伊木马”;大概意思就是希腊人围困了特洛伊人十多年,久攻不下,心生一计,把营盘都撤了,只留下一个巨大的木马(里面装着士兵),以及这位被扒光还被打得够呛的人,也就是此处要谈的主角sinon 虽然 Jest 本身也有一些实现 spy 等的手段,但 sinon 使用起来更加方便。 III.
避免在Sinon中使用箭头函数 与Mocha类似,在Sinon.js中使用箭头函数也可能导致问题。 问题出在sinon.test上。 解决方案是要么在使用sinon.test时避免使用箭头函数,要么通过beforeEach和afterEach来手工初始化和释放测试替身: var sandbox; beforeEach(() => { sandbox = sinon.sandbox.create(); }); afterEach(() => { sandbox.restore(); }); it('should do something with a sandbox', () => { // 与sinon.test类似,这个stub会自动被清理 var stub = sandbox.stub(); }); Mocha自带Promise
Sinon Sinon.JS 为 JavaScript 提供了独立的 spies、stubs 和 mocks [译者注:Spy、Stub 和 Mock 都是测试专用名词,Stub 常被翻译为桩,spies