sinon.js を自習メモ
あらすじ
sinon.js の使い方を毎回 Google 先生に何でしたっけ?って聞くので自分のブログに書いておきます。 せっかくなので覚えたての jsdom も使いたいと思います。
引用元
この記事は下記を自分向けに編集したものです。
- http://qiita.com/halhide/items/498f094ac670884e55c9
- http://dev.classmethod.jp/etc/javascript_testing_framework_sinonjs-1/
- http://codezine.jp/article/detail/7729
準備
% mkdir practice-sinon && cd $_ % npm init -f && npm install sinon jsdom jquery w3c-xmlhttprequest babel mocha power-assert --save-dev
create: test/browser.js
import jsdom from 'jsdom'; import jQuery from 'jquery'; import { XMLHttpRequest } from 'w3c-xmlhttprequest'; global.XMLHttpRequest = XMLHttpRequest; global.window = jsdom.jsdom('<!doctype html><html><body></body></html>').defaultView; global.document = global.window.document; global.$ = jQuery(global.window);
create: test/test_sinon.js
import './browser'; import sinon from 'sinon'; import assert from 'power-assert'; describe('FakeServer in node.js', () => { let server; let spy; beforeEach(() => { server = sinon.fakeServer.create(); spy = sinon.spy(); }); afterEach(() => { server.restore(); }); it('should return fake response', () => { server.respondWith('GET', '/sample.json', [ 200, { 'Content-Type': 'application/json' }, JSON.stringify({message: 'Hello World'}) ]); $.getJSON('/sample.json').then((data) => { spy(data); }); server.respond(); assert.ok(spy.calledWith({message: 'Hello World'})); }); });
実行
% $(npm bin)/mocha --compilers js:babel/register FakeServer in node.js ✓ should return fake response 1 passing (51ms)
Sinon.js について
以下の機能が存在します
- spy: 関数がどのように呼び出されたかを記録する
- stub: 関数の戻り値をあらかじめ設定し、その結果でテストを行う
- mock: 実行前に関数の実行回数など期待する結果を指定しておく
- fake server: 問い合わせるDBやサーバ処理などを単純な実装に置き換える
spy
spy で行うこと
- スパイオブジェクトを作成し、関数を監視する
- 監視対象の関数を実行する
- スパイオブジェクトを確認する
- スパイオブジェクトをクリアする
stub
割愛
mock
割愛
fake
test/test_sion.js
import './browser'; import sinon from 'sinon'; import assert from 'power-assert'; describe('FakeServer in node.js', () => { it('spy', () => { let spy = sinon.spy($, "ajax"); $.getJSON("/some/resource") assert.ok(spy.calledOnce , "method is called once"); assert.equal(spy.getCall(0).args[0].url, "/some/resource", "url parameter"); assert.equal(spy.getCall(0).args[0].dataType, "json", "dataType parameter"); $.ajax.restore(); }); class Human { constructor(name) { this.name = name } hello(friendName) { return "hello, " + friendName + ". I'm " + this.name + "."; } } it('stub', () => { let human = new Human('jordan'); let stub = sinon.stub(human, "hello"); stub.returns("hello?"); stub.withArgs("taro").returns("hello??"); stub.withArgs("jiro").returns("hello???"); assert.ok(human.hello() === "hello?"); assert.ok(human.hello("taro") === "hello??"); assert.ok(human.hello("jiro") === "hello???"); human.hello.restore(); }); it('mock', () => { let human = new Human('kobe'); let mock = sinon.mock(human); mock.expects("hello").twice(); human.hello("taro"); human.hello("jiro"); assert.ok(mock.verify()) }); it("fake server", function(){ let server = sinon.fakeServer.create(); server.respondWith("GET", "./resouces/test1.json", [200, {"Content-Type":"application/json"}, '[{"id":12, "comment":"Hey there"}]']); let spy = sinon.spy(); $.getJSON("./resouces/test1.json", spy); server.respond(); assert.ok(spy.calledWith([{id:12, comment:"Hey there"}])); server.restore(); }); });