SlideShare a Scribd company logo
1 of 25
Download to read offline
+ Sinon.JS

BACKBONE.JSにJasmineでテストコード書いてみた
2013/10/16(水) JSテスト勉強会@福岡 第1回 LT資料
写真はWeb制作向け無料写真素材/ぱくたそ http://www.pakutaso.comを使ってます。ありがとうございます。
13年10月16日水曜日
自己紹介です
========
- twitter: @itokami1123
- 下請けやら派遣やらなんやら開発してます
- JavaEE6と会計の勉強はじめました。
- 目標
 業務系Webアプリの世界にもJavaScriptMVCを!
コミュニティの力で福岡を一つにして
 景気をよくする!(一生福岡でPGしたいっす)
 

13年10月16日水曜日
今日の資料おかしいと思ったら
途中でビシバシ 突っ込んでね!
(優しく)

13年10月16日水曜日
BACKBONE.JSで書いていると
ソースが Model View に分かれます!

13年10月16日水曜日
と言う事は
時間がなくても Modelだけ
テストコードかけるかも!?

13年10月16日水曜日
↑のような画面を作ってるときの...

13年10月16日水曜日
↑の一行明細のModelデータをテスト!

13年10月16日水曜日
メニュー表項目(1行分データ)Modelに
var MenuItem = Backbone.Model.extend({
defaults: function(){
return {
name: "",
price: 0 ,
selected: false
};
},
toggleSelected: function(){
var putData={"selected": !this.get("selected")};
this.save( putData, {wait: true});
}
});

13年10月16日水曜日
オブジェクト生成のテスト!
var MenuItem = Backbone.Model.extend({
defaults: function(){
return {
name: "",
price: 0 ,
selected: false
};

describe ("MenuItem", function() {
var menuItem;
beforeEach(function() {
menuItem = new MenuItem();
});

},

afterEach(function() {
toggleSelected: function(){
menuItem.destroy();
menuItem = null;
var putData={"selected": !this.get("selected")};
});
this.save( putData);
}



describe( "オブジェクト生成時", function() {





it( "初期値としてデフォルト値が設定される事", function() {

});

expect(menuItem).toBeDefined();
expect(menuItem.get("name")).toBe("");
expect(menuItem.get("price")).toBe(0);
expect(menuItem.get("selected")).toBe(false);
});
});
});

13年10月16日水曜日
オブジェクト生成時テストはグリーン!やったね!
var MenuItem = Backbone.Model.extend({
defaults: function(){
return {
name: "",
price: 0 ,
selected: false
};

describe ("MenuItem", function() {
var menuItem;
beforeEach(function() {
menuItem = new MenuItem();
});

},

afterEach(function() {
toggleSelected: function(){
menuItem.destroy();
menuItem = null;
var putData={"selected": !this.get("selected")};
});
this.save( putData);
}



describe( "オブジェクト生成時", function() {





it( "初期値としてデフォルト値が設定される事", function() {

});

expect(menuItem).toBeDefined();
expect(menuItem.get("name")).toBe("");
expect(menuItem.get("price")).toBe(0);
expect(menuItem.get("selected")).toBe(false);
});
});
});

13年10月16日水曜日
次はメニューボタンのON/OFFの切り替えテスト!
var MenuItem = Backbone.Model.extend({
・・・省略・・・

});

toggleSelected: function(){
var putData={
"selected": !this.get("selected")
};
this.save( putData, {wait: true});
}

describe ("MenuItem", function() {
var menuItem;
beforeEach(function() {
menuItem = new MenuItem();
});
afterEach(function() {
menuItem.destroy();
menuItem = null;
});


describe( "メニュー選択時", function(){





it( "トグル選択される事", function(){
expect(menuItem).toBeDefined();
expect(menuItem.get("selected")).toBeFalsy();
menuItem.toggleSelected();
expect(menuItem.get("selected")).toBeTrusy();
});

});
});
13年10月16日水曜日
ぐぁぁぁぁぁ...、Σ( ` o ‘
var MenuItem = Backbone.Model.extend({
・・・省略・・・

});

toggleSelected: function(){
var putData={
"selected": !this.get("selected")
};
this.save( putData, {wait: true});
}

describe ("MenuItem", function() {
var menuItem;
beforeEach(function() {
menuItem = new MenuItem();
});
afterEach(function() {
menuItem.destroy();
menuItem = null;
});


describe( "メニュー選択時", function(){





it( "トグル選択される事", function(){
expect(menuItem).toBeDefined();
expect(menuItem.get("selected")).toBeFalsy();
menuItem.toggleSelected();
expect(menuItem.get("selected")).toBeTrusy();
});

});
});
13年10月16日水曜日
な、なんで...Σ( ` o ‘
var MenuItem = Backbone.Model.extend({
・・・省略・・・

});

toggleSelected: function(){
var putData={
"selected": !this.get("selected")
};
this.save( putData, {wait: true});
}

describe ("MenuItem", function() {
var menuItem;
サーバにPUT更新するリクエストを単体で
beforeEach(function() {
動作させる必要がある作りでした...
menuItem = new MenuItem();
});
afterEach(function() {
menuItem.destroy();
menuItem = null;
});


describe( "メニュー選択時", function(){





it( "トグル選択される事", function(){
expect(menuItem).toBeDefined();
expect(menuItem.get("selected")).toBeFalsy();
menuItem.toggleSelected();
expect(menuItem.get("selected")).toBeTrusy();
});

});
});
13年10月16日水曜日
そこでSinon.JS使います!

http://sinonjs.org/
13年10月16日水曜日
テストコードを書き直しました〜。
var MenuItem = Backbone.Model.extend({
・・・省略・・・

});

describe ("MenuItem", function() {
describe( "メニュー選択時", function(){

toggleSelected: function(){
var putData={
"selected": !this.get("selected")
};
this.save( putData, {wait: true});
}

Sinon.jsの機能で
ダミーの応答を返す!

ダミーで返す値を
細かく指定できます!

});

13年10月16日水曜日

var menuItem,server;
beforeEach( function(){
menuItem = new MenuItem({
"id": 1, "name": "test",
"price": 100, "selected": false
});
menuItem.url = "/unitTestUrl";
server = sinon.fakeServer.create();
});
afterEach(function () {
server.restore();
});
it( "トグル選択される事", function(){
expect(menuItem).toBeDefined();
expect(menuItem.get("selected")).toBeFalsy();
server.respondWith(
"PUT","/unitTestUrl",[
200,
{"Content-Type": "application/json"},
'{"id":1,"name":"test","price":100,"selected":true}'
]);
menuItem.toggleSelected();
server.respond();
expect(menuItem.get("selected")).toBeTruthy();
});
});
次は↑の明細複数行のModelデータをテスト!

13年10月16日水曜日
明細複数行Model(Collection)に
var MenuList = Backbone.Collection.extend({
model: MenuItem,
comparator: 'id'
sumPrice: function(){
var sum = 0,
selectedMenuItems = this.where({ selected:true });
_.each( selectedMenuItems, function( model){
sum += model.get( "price");
});
return sum;
},
createMenu: function(name,price){
var menuItemData = {
name:name,
price:price,
selected:false
};
this.create(menuItemData, {wait: true});
},
});

13年10月16日水曜日
合計金額算出のテストケース追加!
var MenuList = Backbone.Collection.extend({
model: MenuItem,
comparator: 'id'
sumPrice: function(){
var sum = 0,
selectedMenuItems = this.where({ selected:true });
_.each( selectedMenuItems, function( model){
sum += model.get( "price");
});
return sum;
},
createMenu: function(name,price){
describe ( "MenuList", function() {
var menuItemData = {
name:name,
describe ( "選択メニュー合計金額算出", function() {
price:price,
selected:false
it( "格納モデルの選択中より合計金額を算出する", function() {
};
this.create(menuItemData, {wait: true});
var menuList = new MenuList([
},
{ name:"a", price: 100, selected: true},
{ name:"b", price: 200, selected: false},
});
{ name:"c", price: 400, selected: true},
]);
expect( menuList.sumPrice()).toBe( 500);
});
});

13年10月16日水曜日

});
合計金額算出のテストはOK(グリーン)!\(^o^)/
var MenuList = Backbone.Collection.extend({
model: MenuItem,
comparator: 'id'
sumPrice: function(){
var sum = 0,
selectedMenuItems = this.where({ selected:true });
_.each( selectedMenuItems, function( model){
sum += model.get( "price");
});
return sum;
},
createMenu: function(name,price){
describe ( "MenuList", function() {
var menuItemData = {
name:name,
describe ( "選択メニュー合計金額算出", function() {
price:price,
selected:false
it( "格納モデルの選択中より合計金額を算出する", function() {
};
this.create(menuItemData, {wait: true});
var menuList = new MenuList([
},
{ name:"a", price: 100, selected: true},
{ name:"b", price: 200, selected: false},
});
{ name:"c", price: 400, selected: true},
]);
expect( menuList.sumPrice()).toBe( 500);
});
});

13年10月16日水曜日

});
次は新規メニュー登録のテストケース追加!
var MenuList = Backbone.Collection.extend({
model: MenuItem,
comparator: 'id'
describe ( "MenuList", function() {
// ・・・省略・・・

sumPrice: function(){
var sum = 0,

describe( "新規メニュー表登録", function() {
selectedMenuItems = this.where({ selected:true });


it( "サーバより返却された名称と金額が設定されること", function(){
_.each( selectedMenuItems, function( model){
sum += model.get( "price");
server = sinon.fakeServer.create();
});
var menuList = new MenuList();
return sum;
menuList.url = "/unitTestUrl";
},
server.respondWith([
200,
{"Content-Type": "application/json"},
'{"id":123,"name":"sevNam",
"price":1005,"selected":false}'

createMenu: function(name,price){
var menuItemData = {
name:name,
price:price,
selected:false
};

]);
menuList.createMenu( 'test', 1000);
server.respond();

this.create(
menuItemData,
{wait: true}
);

expect( menuList.size()).toBe( 1);
var model = menuList.get(123);
expect( model.get("name") ).toBe( "sevNam");
expect( model.get("price") ).toBe( 1005);

},
});
});

13年10月16日水曜日

});

})
新規メニュー表登録処理もOK(グリーン)!
var MenuList = Backbone.Collection.extend({
model: MenuItem,
comparator: 'id'
describe ( "MenuList", function() {
// ・・・省略・・・

sumPrice: function(){
var sum = 0,

describe( "新規メニュー表登録", function() {
selectedMenuItems = this.where({ selected:true });


it( "サーバより返却された名称と金額が設定されること", function(){
_.each( selectedMenuItems, function( model){
sum += model.get( "price");
server = sinon.fakeServer.create();
});
var menuList = new MenuList();
return sum;
menuList.url = "/unitTestUrl";
},
server.respondWith([
200,
{"Content-Type": "application/json"},
'{"id":123,"name":"sevNam",
"price":1005,"selected":false}'

createMenu: function(name,price){
var menuItemData = {
name:name,
price:price,
selected:false
};

]);
menuList.createMenu( 'test', 1000);
server.respond();

this.create(
menuItemData,
{wait: true}
);

expect( menuList.size()).toBe( 1);
var model = menuList.get(123);
expect( model.get("name") ).toBe( "sevNam");
expect( model.get("price") ).toBe( 1005);

},
});
});

13年10月16日水曜日

});

})
まとめ

13年10月16日水曜日
まとめです
========
- Backbone.jsのように MV*にすれば
 Modelのみのテストコードが書きやすい!

まとめ

- ModelからのAjax通信も
 Sinon.jsのFakeServerを使えば
 ユニットテストできる!

13年10月16日水曜日
何か質問とか
もっとこうした方が良いよとかありますか??

13年10月16日水曜日
ご清聴ありがとうございました!

今日の資料で出てきたソースは以下で公開してます。
https://github.com/itokami1123dev/hamburger_shop_prj

13年10月16日水曜日

More Related Content

More from Toshio Ehara

iPhoneアプリを Javaで書くよ?
iPhoneアプリを Javaで書くよ?iPhoneアプリを Javaで書くよ?
iPhoneアプリを Javaで書くよ?Toshio Ehara
 
Java初心者勉強会(2015/08/07)資料
Java初心者勉強会(2015/08/07)資料Java初心者勉強会(2015/08/07)資料
Java初心者勉強会(2015/08/07)資料Toshio Ehara
 
Java電卓勉強会資料
Java電卓勉強会資料Java電卓勉強会資料
Java電卓勉強会資料Toshio Ehara
 
BABELで、ES2015(ES6)を学ぼう!
BABELで、ES2015(ES6)を学ぼう!BABELで、ES2015(ES6)を学ぼう!
BABELで、ES2015(ES6)を学ぼう!Toshio Ehara
 
AngularJSで業務システムUI部品化
AngularJSで業務システムUI部品化AngularJSで業務システムUI部品化
AngularJSで業務システムUI部品化Toshio Ehara
 
traceur-compilerで ECMAScript6を体験
traceur-compilerで ECMAScript6を体験traceur-compilerで ECMAScript6を体験
traceur-compilerで ECMAScript6を体験Toshio Ehara
 
traceur-compilerで未来のJavaScriptを体験
traceur-compilerで未来のJavaScriptを体験traceur-compilerで未来のJavaScriptを体験
traceur-compilerで未来のJavaScriptを体験Toshio Ehara
 
AngularJS入門の巻2
AngularJS入門の巻2AngularJS入門の巻2
AngularJS入門の巻2Toshio Ehara
 
JenkinsをJava開発でこんな感じで使っています
JenkinsをJava開発でこんな感じで使っていますJenkinsをJava開発でこんな感じで使っています
JenkinsをJava開発でこんな感じで使っていますToshio Ehara
 
AngularJS入門の巻
AngularJS入門の巻AngularJS入門の巻
AngularJS入門の巻Toshio Ehara
 
AngularJS+TypeScriptを試してみた。
AngularJS+TypeScriptを試してみた。AngularJS+TypeScriptを試してみた。
AngularJS+TypeScriptを試してみた。Toshio Ehara
 
AngularJSのDirectiveで俺俺タグつくっちゃお
AngularJSのDirectiveで俺俺タグつくっちゃおAngularJSのDirectiveで俺俺タグつくっちゃお
AngularJSのDirectiveで俺俺タグつくっちゃおToshio Ehara
 
HTML5のCanvas入門 - Img画像を編集してみよう -
HTML5のCanvas入門 - Img画像を編集してみよう -HTML5のCanvas入門 - Img画像を編集してみよう -
HTML5のCanvas入門 - Img画像を編集してみよう -Toshio Ehara
 
BACKBONEJS+SCSS+JavaEE(JAX-RS) 今風のWebアプリをNetBeansで入門!
BACKBONEJS+SCSS+JavaEE(JAX-RS) 今風のWebアプリをNetBeansで入門!BACKBONEJS+SCSS+JavaEE(JAX-RS) 今風のWebアプリをNetBeansで入門!
BACKBONEJS+SCSS+JavaEE(JAX-RS) 今風のWebアプリをNetBeansで入門!Toshio Ehara
 
福岡のIT勉強会情報の集め方(LT資料)
福岡のIT勉強会情報の集め方(LT資料)福岡のIT勉強会情報の集め方(LT資料)
福岡のIT勉強会情報の集め方(LT資料)Toshio Ehara
 
BACKBONE.JSによるWebアプリケーション開発について
BACKBONE.JSによるWebアプリケーション開発についてBACKBONE.JSによるWebアプリケーション開発について
BACKBONE.JSによるWebアプリケーション開発についてToshio Ehara
 
JavaScriptのテストコード 一緒に勉強しませんか??
JavaScriptのテストコード 一緒に勉強しませんか??JavaScriptのテストコード 一緒に勉強しませんか??
JavaScriptのテストコード 一緒に勉強しませんか??Toshio Ehara
 
【未発表】Backbone.jsとJavaEE7でWebアプリを作ろう!(第1回) 〜GETで一覧編〜
【未発表】Backbone.jsとJavaEE7でWebアプリを作ろう!(第1回) 〜GETで一覧編〜【未発表】Backbone.jsとJavaEE7でWebアプリを作ろう!(第1回) 〜GETで一覧編〜
【未発表】Backbone.jsとJavaEE7でWebアプリを作ろう!(第1回) 〜GETで一覧編〜Toshio Ehara
 
LT Leap MotionとJavaScriptで遊ぼう!
LT Leap MotionとJavaScriptで遊ぼう!LT Leap MotionとJavaScriptで遊ぼう!
LT Leap MotionとJavaScriptで遊ぼう!Toshio Ehara
 
BACKBONE.JSでMVC始めませんか?
BACKBONE.JSでMVC始めませんか?BACKBONE.JSでMVC始めませんか?
BACKBONE.JSでMVC始めませんか?Toshio Ehara
 

More from Toshio Ehara (20)

iPhoneアプリを Javaで書くよ?
iPhoneアプリを Javaで書くよ?iPhoneアプリを Javaで書くよ?
iPhoneアプリを Javaで書くよ?
 
Java初心者勉強会(2015/08/07)資料
Java初心者勉強会(2015/08/07)資料Java初心者勉強会(2015/08/07)資料
Java初心者勉強会(2015/08/07)資料
 
Java電卓勉強会資料
Java電卓勉強会資料Java電卓勉強会資料
Java電卓勉強会資料
 
BABELで、ES2015(ES6)を学ぼう!
BABELで、ES2015(ES6)を学ぼう!BABELで、ES2015(ES6)を学ぼう!
BABELで、ES2015(ES6)を学ぼう!
 
AngularJSで業務システムUI部品化
AngularJSで業務システムUI部品化AngularJSで業務システムUI部品化
AngularJSで業務システムUI部品化
 
traceur-compilerで ECMAScript6を体験
traceur-compilerで ECMAScript6を体験traceur-compilerで ECMAScript6を体験
traceur-compilerで ECMAScript6を体験
 
traceur-compilerで未来のJavaScriptを体験
traceur-compilerで未来のJavaScriptを体験traceur-compilerで未来のJavaScriptを体験
traceur-compilerで未来のJavaScriptを体験
 
AngularJS入門の巻2
AngularJS入門の巻2AngularJS入門の巻2
AngularJS入門の巻2
 
JenkinsをJava開発でこんな感じで使っています
JenkinsをJava開発でこんな感じで使っていますJenkinsをJava開発でこんな感じで使っています
JenkinsをJava開発でこんな感じで使っています
 
AngularJS入門の巻
AngularJS入門の巻AngularJS入門の巻
AngularJS入門の巻
 
AngularJS+TypeScriptを試してみた。
AngularJS+TypeScriptを試してみた。AngularJS+TypeScriptを試してみた。
AngularJS+TypeScriptを試してみた。
 
AngularJSのDirectiveで俺俺タグつくっちゃお
AngularJSのDirectiveで俺俺タグつくっちゃおAngularJSのDirectiveで俺俺タグつくっちゃお
AngularJSのDirectiveで俺俺タグつくっちゃお
 
HTML5のCanvas入門 - Img画像を編集してみよう -
HTML5のCanvas入門 - Img画像を編集してみよう -HTML5のCanvas入門 - Img画像を編集してみよう -
HTML5のCanvas入門 - Img画像を編集してみよう -
 
BACKBONEJS+SCSS+JavaEE(JAX-RS) 今風のWebアプリをNetBeansで入門!
BACKBONEJS+SCSS+JavaEE(JAX-RS) 今風のWebアプリをNetBeansで入門!BACKBONEJS+SCSS+JavaEE(JAX-RS) 今風のWebアプリをNetBeansで入門!
BACKBONEJS+SCSS+JavaEE(JAX-RS) 今風のWebアプリをNetBeansで入門!
 
福岡のIT勉強会情報の集め方(LT資料)
福岡のIT勉強会情報の集め方(LT資料)福岡のIT勉強会情報の集め方(LT資料)
福岡のIT勉強会情報の集め方(LT資料)
 
BACKBONE.JSによるWebアプリケーション開発について
BACKBONE.JSによるWebアプリケーション開発についてBACKBONE.JSによるWebアプリケーション開発について
BACKBONE.JSによるWebアプリケーション開発について
 
JavaScriptのテストコード 一緒に勉強しませんか??
JavaScriptのテストコード 一緒に勉強しませんか??JavaScriptのテストコード 一緒に勉強しませんか??
JavaScriptのテストコード 一緒に勉強しませんか??
 
【未発表】Backbone.jsとJavaEE7でWebアプリを作ろう!(第1回) 〜GETで一覧編〜
【未発表】Backbone.jsとJavaEE7でWebアプリを作ろう!(第1回) 〜GETで一覧編〜【未発表】Backbone.jsとJavaEE7でWebアプリを作ろう!(第1回) 〜GETで一覧編〜
【未発表】Backbone.jsとJavaEE7でWebアプリを作ろう!(第1回) 〜GETで一覧編〜
 
LT Leap MotionとJavaScriptで遊ぼう!
LT Leap MotionとJavaScriptで遊ぼう!LT Leap MotionとJavaScriptで遊ぼう!
LT Leap MotionとJavaScriptで遊ぼう!
 
BACKBONE.JSでMVC始めませんか?
BACKBONE.JSでMVC始めませんか?BACKBONE.JSでMVC始めませんか?
BACKBONE.JSでMVC始めませんか?
 

Recently uploaded

Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Danieldanielhu54
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものですiPride Co., Ltd.
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムsugiuralab
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNetToru Tamaki
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略Ryo Sasaki
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)Hiroki Ichikura
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdftaisei2219
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Yuma Ohgami
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...Toru Tamaki
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A surveyToru Tamaki
 

Recently uploaded (10)

Postman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By DanielPostman LT Fukuoka_Quick Prototype_By Daniel
Postman LT Fukuoka_Quick Prototype_By Daniel
 
SOPを理解する 2024/04/19 の勉強会で発表されたものです
SOPを理解する       2024/04/19 の勉強会で発表されたものですSOPを理解する       2024/04/19 の勉強会で発表されたものです
SOPを理解する 2024/04/19 の勉強会で発表されたものです
 
スマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システムスマートフォンを用いた新生児あやし動作の教示システム
スマートフォンを用いた新生児あやし動作の教示システム
 
論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet論文紹介:Automated Classification of Model Errors on ImageNet
論文紹介:Automated Classification of Model Errors on ImageNet
 
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
[DevOpsDays Tokyo 2024] 〜デジタルとアナログのはざまに〜 スマートビルディング爆速開発を支える 自動化テスト戦略
 
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
【早稲田AI研究会 講義資料】3DスキャンとTextTo3Dのツールを知ろう!(Vol.1)
 
TSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdfTSAL operation mechanism and circuit diagram.pdf
TSAL operation mechanism and circuit diagram.pdf
 
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
Open Source UN-Conference 2024 Kawagoe - 独自OS「DaisyOS GB」の紹介
 
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
論文紹介:Content-Aware Token Sharing for Efficient Semantic Segmentation With Vis...
 
論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey論文紹介:Semantic segmentation using Vision Transformers: A survey
論文紹介:Semantic segmentation using Vision Transformers: A survey
 

BACKBONE.JSにJasmineでテストコード書いてみた (LT資料)

  • 1. + Sinon.JS BACKBONE.JSにJasmineでテストコード書いてみた 2013/10/16(水) JSテスト勉強会@福岡 第1回 LT資料 写真はWeb制作向け無料写真素材/ぱくたそ http://www.pakutaso.comを使ってます。ありがとうございます。 13年10月16日水曜日
  • 2. 自己紹介です ======== - twitter: @itokami1123 - 下請けやら派遣やらなんやら開発してます - JavaEE6と会計の勉強はじめました。 - 目標  業務系Webアプリの世界にもJavaScriptMVCを! コミュニティの力で福岡を一つにして  景気をよくする!(一生福岡でPGしたいっす)   13年10月16日水曜日
  • 4. BACKBONE.JSで書いていると ソースが Model View に分かれます! 13年10月16日水曜日
  • 8. メニュー表項目(1行分データ)Modelに var MenuItem = Backbone.Model.extend({ defaults: function(){ return { name: "", price: 0 , selected: false }; }, toggleSelected: function(){ var putData={"selected": !this.get("selected")}; this.save( putData, {wait: true}); } }); 13年10月16日水曜日
  • 9. オブジェクト生成のテスト! var MenuItem = Backbone.Model.extend({ defaults: function(){ return { name: "", price: 0 , selected: false }; describe ("MenuItem", function() { var menuItem; beforeEach(function() { menuItem = new MenuItem(); }); }, afterEach(function() { toggleSelected: function(){ menuItem.destroy(); menuItem = null; var putData={"selected": !this.get("selected")}; }); this.save( putData); } describe( "オブジェクト生成時", function() { it( "初期値としてデフォルト値が設定される事", function() { }); expect(menuItem).toBeDefined(); expect(menuItem.get("name")).toBe(""); expect(menuItem.get("price")).toBe(0); expect(menuItem.get("selected")).toBe(false); }); }); }); 13年10月16日水曜日
  • 10. オブジェクト生成時テストはグリーン!やったね! var MenuItem = Backbone.Model.extend({ defaults: function(){ return { name: "", price: 0 , selected: false }; describe ("MenuItem", function() { var menuItem; beforeEach(function() { menuItem = new MenuItem(); }); }, afterEach(function() { toggleSelected: function(){ menuItem.destroy(); menuItem = null; var putData={"selected": !this.get("selected")}; }); this.save( putData); } describe( "オブジェクト生成時", function() { it( "初期値としてデフォルト値が設定される事", function() { }); expect(menuItem).toBeDefined(); expect(menuItem.get("name")).toBe(""); expect(menuItem.get("price")).toBe(0); expect(menuItem.get("selected")).toBe(false); }); }); }); 13年10月16日水曜日
  • 11. 次はメニューボタンのON/OFFの切り替えテスト! var MenuItem = Backbone.Model.extend({ ・・・省略・・・ }); toggleSelected: function(){ var putData={ "selected": !this.get("selected") }; this.save( putData, {wait: true}); } describe ("MenuItem", function() { var menuItem; beforeEach(function() { menuItem = new MenuItem(); }); afterEach(function() { menuItem.destroy(); menuItem = null; }); describe( "メニュー選択時", function(){ it( "トグル選択される事", function(){ expect(menuItem).toBeDefined(); expect(menuItem.get("selected")).toBeFalsy(); menuItem.toggleSelected(); expect(menuItem.get("selected")).toBeTrusy(); }); }); }); 13年10月16日水曜日
  • 12. ぐぁぁぁぁぁ...、Σ( ` o ‘ var MenuItem = Backbone.Model.extend({ ・・・省略・・・ }); toggleSelected: function(){ var putData={ "selected": !this.get("selected") }; this.save( putData, {wait: true}); } describe ("MenuItem", function() { var menuItem; beforeEach(function() { menuItem = new MenuItem(); }); afterEach(function() { menuItem.destroy(); menuItem = null; }); describe( "メニュー選択時", function(){ it( "トグル選択される事", function(){ expect(menuItem).toBeDefined(); expect(menuItem.get("selected")).toBeFalsy(); menuItem.toggleSelected(); expect(menuItem.get("selected")).toBeTrusy(); }); }); }); 13年10月16日水曜日
  • 13. な、なんで...Σ( ` o ‘ var MenuItem = Backbone.Model.extend({ ・・・省略・・・ }); toggleSelected: function(){ var putData={ "selected": !this.get("selected") }; this.save( putData, {wait: true}); } describe ("MenuItem", function() { var menuItem; サーバにPUT更新するリクエストを単体で beforeEach(function() { 動作させる必要がある作りでした... menuItem = new MenuItem(); }); afterEach(function() { menuItem.destroy(); menuItem = null; }); describe( "メニュー選択時", function(){ it( "トグル選択される事", function(){ expect(menuItem).toBeDefined(); expect(menuItem.get("selected")).toBeFalsy(); menuItem.toggleSelected(); expect(menuItem.get("selected")).toBeTrusy(); }); }); }); 13年10月16日水曜日
  • 15. テストコードを書き直しました〜。 var MenuItem = Backbone.Model.extend({ ・・・省略・・・ }); describe ("MenuItem", function() { describe( "メニュー選択時", function(){ toggleSelected: function(){ var putData={ "selected": !this.get("selected") }; this.save( putData, {wait: true}); } Sinon.jsの機能で ダミーの応答を返す! ダミーで返す値を 細かく指定できます! }); 13年10月16日水曜日 var menuItem,server; beforeEach( function(){ menuItem = new MenuItem({ "id": 1, "name": "test", "price": 100, "selected": false }); menuItem.url = "/unitTestUrl"; server = sinon.fakeServer.create(); }); afterEach(function () { server.restore(); }); it( "トグル選択される事", function(){ expect(menuItem).toBeDefined(); expect(menuItem.get("selected")).toBeFalsy(); server.respondWith( "PUT","/unitTestUrl",[ 200, {"Content-Type": "application/json"}, '{"id":1,"name":"test","price":100,"selected":true}' ]); menuItem.toggleSelected(); server.respond(); expect(menuItem.get("selected")).toBeTruthy(); }); });
  • 17. 明細複数行Model(Collection)に var MenuList = Backbone.Collection.extend({ model: MenuItem, comparator: 'id' sumPrice: function(){ var sum = 0, selectedMenuItems = this.where({ selected:true }); _.each( selectedMenuItems, function( model){ sum += model.get( "price"); }); return sum; }, createMenu: function(name,price){ var menuItemData = { name:name, price:price, selected:false }; this.create(menuItemData, {wait: true}); }, }); 13年10月16日水曜日
  • 18. 合計金額算出のテストケース追加! var MenuList = Backbone.Collection.extend({ model: MenuItem, comparator: 'id' sumPrice: function(){ var sum = 0, selectedMenuItems = this.where({ selected:true }); _.each( selectedMenuItems, function( model){ sum += model.get( "price"); }); return sum; }, createMenu: function(name,price){ describe ( "MenuList", function() { var menuItemData = { name:name, describe ( "選択メニュー合計金額算出", function() { price:price, selected:false it( "格納モデルの選択中より合計金額を算出する", function() { }; this.create(menuItemData, {wait: true}); var menuList = new MenuList([ }, { name:"a", price: 100, selected: true}, { name:"b", price: 200, selected: false}, }); { name:"c", price: 400, selected: true}, ]); expect( menuList.sumPrice()).toBe( 500); }); }); 13年10月16日水曜日 });
  • 19. 合計金額算出のテストはOK(グリーン)!\(^o^)/ var MenuList = Backbone.Collection.extend({ model: MenuItem, comparator: 'id' sumPrice: function(){ var sum = 0, selectedMenuItems = this.where({ selected:true }); _.each( selectedMenuItems, function( model){ sum += model.get( "price"); }); return sum; }, createMenu: function(name,price){ describe ( "MenuList", function() { var menuItemData = { name:name, describe ( "選択メニュー合計金額算出", function() { price:price, selected:false it( "格納モデルの選択中より合計金額を算出する", function() { }; this.create(menuItemData, {wait: true}); var menuList = new MenuList([ }, { name:"a", price: 100, selected: true}, { name:"b", price: 200, selected: false}, }); { name:"c", price: 400, selected: true}, ]); expect( menuList.sumPrice()).toBe( 500); }); }); 13年10月16日水曜日 });
  • 20. 次は新規メニュー登録のテストケース追加! var MenuList = Backbone.Collection.extend({ model: MenuItem, comparator: 'id' describe ( "MenuList", function() { // ・・・省略・・・ sumPrice: function(){ var sum = 0, describe( "新規メニュー表登録", function() { selectedMenuItems = this.where({ selected:true }); it( "サーバより返却された名称と金額が設定されること", function(){ _.each( selectedMenuItems, function( model){ sum += model.get( "price"); server = sinon.fakeServer.create(); }); var menuList = new MenuList(); return sum; menuList.url = "/unitTestUrl"; }, server.respondWith([ 200, {"Content-Type": "application/json"}, '{"id":123,"name":"sevNam", "price":1005,"selected":false}' createMenu: function(name,price){ var menuItemData = { name:name, price:price, selected:false }; ]); menuList.createMenu( 'test', 1000); server.respond(); this.create( menuItemData, {wait: true} ); expect( menuList.size()).toBe( 1); var model = menuList.get(123); expect( model.get("name") ).toBe( "sevNam"); expect( model.get("price") ).toBe( 1005); }, }); }); 13年10月16日水曜日 }); })
  • 21. 新規メニュー表登録処理もOK(グリーン)! var MenuList = Backbone.Collection.extend({ model: MenuItem, comparator: 'id' describe ( "MenuList", function() { // ・・・省略・・・ sumPrice: function(){ var sum = 0, describe( "新規メニュー表登録", function() { selectedMenuItems = this.where({ selected:true }); it( "サーバより返却された名称と金額が設定されること", function(){ _.each( selectedMenuItems, function( model){ sum += model.get( "price"); server = sinon.fakeServer.create(); }); var menuList = new MenuList(); return sum; menuList.url = "/unitTestUrl"; }, server.respondWith([ 200, {"Content-Type": "application/json"}, '{"id":123,"name":"sevNam", "price":1005,"selected":false}' createMenu: function(name,price){ var menuItemData = { name:name, price:price, selected:false }; ]); menuList.createMenu( 'test', 1000); server.respond(); this.create( menuItemData, {wait: true} ); expect( menuList.size()).toBe( 1); var model = menuList.get(123); expect( model.get("name") ).toBe( "sevNam"); expect( model.get("price") ).toBe( 1005); }, }); }); 13年10月16日水曜日 }); })
  • 23. まとめです ======== - Backbone.jsのように MV*にすれば  Modelのみのテストコードが書きやすい! まとめ - ModelからのAjax通信も  Sinon.jsのFakeServerを使えば  ユニットテストできる! 13年10月16日水曜日