Weitere ähnliche Inhalte Ähnlich wie 基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~ (20) 基礎から見直す ASP.NET MVC の単体テスト自動化方法 ~ Windows Azure 関連もあるかも~1. 基礎から見直す ASP.NET MVC
の単体テスト自動化方法
~ Windows Azure 関連もあるかも~
Microsft MVP for Windows Azure
割と普通
1
2. 自己紹介
• 割と普通 ( @normalian )
– Windows Azure のコミュニティメンバ
• Japan Windows Azure User Group
http://r.jazug.jp/
– わんくま同盟 のコミュニティメンバ
• http://www.wankuma.com/
– Microsoft MVP for Windows Azure 2010~
2
3. 本セッションの目的とゴール
• 目的
– C#/VB.NET で単体テスト自動化するため、どのよ
うにテストコードを記述すれば良いかを認知
– 単体テスト自動化を支援するツール、ライブラリ群を
認知
• ゴール
– C#/VB.NET で、単体テストの自動化が可能なテ
ストコードを効率的に記述することができる
3
10. 単体テストの対象を明確化する
• データの入出力ポイントに対して単
体テストを実施する モデルのテスト
HTML/ Java 画面 コント モデル
CSS Script モデル ローラ
JavaScript で記 JavaScript から
コントローラの
述したロジック C# へのマッピ
テスト
のテスト ング JavaScript
C#
10
11. 単体テスト自動化が容易なインター
フェースを定義する 1/3
• 従来の ASP.NET Web Forms では、単体テ
ストの自動化がきわめて困難
メインコード
テストコード
13. 単体テスト自動化が容易なインター
フェースを定義する 3/3
• Testing Framework や NUnit 等で自動テ
スト可能な外部インターフェース設計とする
ViewReult コント
• ViewBag ローラ
• Model
Web API の
応答
XXXXResult
(その他の応答)
13
14. 変数名の命名規則に留意する 1/2
• テストメソッド名、変数名からチェック対象を理解
できるように命名する
良い例
[TestMethod]
public void Indexがリストを返す()
{
List<string> expect = new List<string>(){ "a", "b", "c" };
List<string> actual = null;
HomeController controller = new HomeController();
actual = (controller.Index() as ViewResult).Model;
Assert.Equals( expect, actual );
}
14
15. 変数名の命名規則に留意する 2/2
• 「悪い例」では、テストメソッド名、変数名から
チェック対象が理解できない
悪い例
[TestMethod]
public void Index ()
{
HomeController controller = new HomeController();
var actual = (controller.Index() as ViewResult).Model;
Assert.Equals(new List<string>(){ "a", "b", "c" }, actual );
}
15
18. モックを効率的に作成する 1/2
• Moq.dll 等を利用して HttpContextBase,
IPrincipal, IIdentity 等のモック作成が難しい
クラスを作成する
[TestMethod()]
public void IndexTest01()
{
• Moq.dll を利用してもス
string expect = typeof(RedirectToRouteResult).FullName;
string actual;
BuyHistoryController target = new BuyHistoryController(new TestOrderRepository());
テップ数が多い
//モックの作成
var mockHttpContextBase = new Mock<HttpContextBase>();
• Moq.dll を利用しないと
var mockIdentity = new Mock<IIdentity>();
var mockPrincipal = new Mock<IPrincipal>(); 数倍のコード行数になる
//ユーザ情報の設定&httpContextオブジェクトの作成
mockIdentity.Setup(identity => identity.IsAuthenticated).Returns(true);
mockIdentity.Setup(identity => identity.Name).Returns("someUser");
mockPrincipal.Setup(principal => principal.Identity).Returns(mockIdentity.Object);
mockHttpContextBase.Setup(httpContextBase => httpContextBase.User)
.Returns(mockPrincipal.Object);
ControllerContext context = new ControllerContext(mockHttpContextBase.Object, new RouteData(), target);
target.ControllerContext = context;
actual = target.Index().GetType().FullName;
Assert.AreEqual(expect, actual);
}
18
19. モックを効率的に作成する 2/2
• モック作成は行数が伸びるので共通化する
[TestMethod()]
public void IndexTest01(){
string expected= typeof(RedirectToRouteResult).FullName;
string actual;
BuyHistoryController target = モック作成を共通化
new BuyHistoryController(new TestOrderRepository());
ControllerContext context = new ControllerContext(
Utils.CreateControllerContext(true, "someuser")
, new RouteData(), target);
target.ControllerContext = context;
actual = target.Index().GetType().FullName;
Assert.AreEqual(expect, actual);
}
19
20. 名前空間、クラス名の命名規則に留意する
• テスト対象のプロジェクト、クラスが分かりやすいよう
に命名規則を規定する
– プロジェクト名:MyMVC → MyMVC.Test
– クラス名: MyClass → MyClassTest
– メソッド名: MyMethod → MyMethodTest
• 命名規約に従うことで、 TestDriven.NET を利
用した、メインコード/テストコードの切り替えが可能
– http://www.testdriven.net/quickstart.aspx
20
24. ツールを利用したテスト効率化(β)
• 紹介したツール・ライブラリを利用
してテストを自動化する
HTML/ View View コント モデル
QUnit-tap
CSS Model Model Testing
ローラ
で単体テス knocko Framework Entity
ト自動化 ut.map 単体テスト自動化
knock AutoM
Frame
out.js apper
node.exe ping.js MSTest.exe work
JavaScript
C#
24
26. knockout.js
• DOM 要素と JSON オブジェクトのマッピング機能
var viewModel = {
left: ko.observable( 30 ),
right: ko.observable( 40 ) onblur 等のイベントが発生した
}; タイミングで、ViewModel と
viewModel.answer = DOM要素で値を同期
ko.dependentObservable(function () {
return parseInt(this.left()) + parseInt(this.right());
}, viewModel);
ko.applyBindings(viewModel);
<input type=“text” data-bind=“value: left” /> +
<input type=“text” data-bind=“value: right” /> = <span data-
bind="text: answer"></span>
26
27. Knockout.mapping.js 1/2
• C#/VB.NET の ViewModel と JSON オブジェクト
をマッピング { name: “若人”, age: 20}
等のJSONに置換される処理
<script type="text/javascript">
//JSONオブジェクトから、ViewModel を作成
var initialData =
@Html.Raw(Json.Encode(Model));
var viewModel = ko.mapping.fromJS(initialData);
//DOM要素を読み込み後、ViewModel を Binding
$( function(){
ko.applyBindings(viewModel);
});
</script> DOM 要素 と viewModel イ
ンスタンスとを双方向バインド
27
28. Knockout.mapping.js 2/2
• C#/VB.NET の ViewModel と JSON オブジェクト
をマッピング
$.ajax({
type:“POST”, dataType: "json",
contentType: "application/json",
data : ko.mapping.toJSON(viewModel),
url: "@Url.Content("~/api/Values/")",
success :
function(res){ alert(JSON.stringify(res)); }
});
public class ValuesController : ApiController{
public string Post(ViewModel viewModel){
return "server recieved answer = " +
viewModel.answer; }
28
29. AutoMapper
• Model – ViewModel といったモデル間のマッピ
ングを実施する
• 複数モデルからの集約化等、細かな制御が可能
Model ViewModel
項目1
項目2
30. AutoMapper
• 「XXX.ID = YYY.ID」の羅列を防止できる
• マッピングが存在しない場合は一括でチェック可能
Product product = ProductRepository.GetById(id);
Mapping.AutoMapperBootstrapper.Configure();
Mapper.CreateMap<Product, ProductViewModel>();
Mapper.Map<Product, ProductViewModel>(product);
var productViewModel = Mapper.Map<Product,
ProductViewModel>(product);
31. QUnit-tap の利用
• node.exe から実行可能な QUnit
– node.exe → Node.js の Windows 実装
– QUnit → ブラウザ上で JavaScript を単体テスト
• knockout.js の ViewModel が対象?
require('../test_helper.js');
QUnit.test('my calc test', function() {
var expect = 3;
var actual = calc( 1, 2 );
assert.equal(expect, actual);
});
QUnit.start();
33. まとめ
• ASP.NET MVC は単体テストの自動化に向
いている
• 単体テストの自動化を実施するためにはコツ
がある
• 単体テストの自動化を支援するツールは多々
存在する
34. View と コントローラの構成 (β)
HTML/CSS ViewM
View knockout.map Contr Model
knockout.js Model ping.js odel oller Entity
Framework
HTML/CSS ViewM
View knockout.map
knockout.js
Model ping.js odel Model
HTML/CSS View ViewM Entity
knockout.map
knockout.js
Model ping.js odel Framework
1対N N対M
1対1 対応
対応 対応
対応関係
C#
JavaScript
36. 参考 1/2
• InfoQ – ASP.NET MVC のテスト方法
– http://www.infoq.com/jp/news/2012/03/aspnet-
unit-test
• MSDN Library – ASP.NET MVC アプリケーションの単体テスト
– http://msdn.microsoft.com/ja-
jp/library/ff936235.aspx
• ASP.NET MVC3 における単体テストの基礎
– http://codezine.jp/article/detail/6493
• wa りと na はてな日記 - Moq.dll on ASP.NET MVC その2
– http://d.hatena.ne.jp/waritohutsu/20090909/
37. 参考 2/2
• knockout.js Documentation > mapping
– http://knockoutjs.com/documentation/plugins-
mapping.html
• knockout.js Documentation > The “template”
binding
– http://knockoutjs.com/documentation/template-
binding.html
• knockout.js の注意すべき点
– http://d.hatena.ne.jp/shiba-yan/20120130/
• miso_soup3 - AutoMapper+ViewModel In MVC その2
– http://d.hatena.ne.jp/miso_soup3/20120408/
42. 自はこ
動ての
テし
スな
トく
坂遠
をい
よ
・
・
・
未
ばのよオ
かぼうレ
りりやは
だはく
かじ
完
らめ
なた