あらすじ
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();
});
});