ASP.NET MVCでテストを書く際に考えたことのメモ
おすすめのパッケージ
Moq
テストのためのダミーオブジェクトを作成するパッケージ。
簡単な使い方
var mock = new Mock<IHelloModel>();
mock.Setup(x => x.Hello()).Returns("test return");
IHelloModel hello = mock.object;
ChainingAssertion
MsTestも手軽にいい感じにかけるパッケージ。
test = "test";
test.Is<string>("test"); // 成功
コントローラのテスト
とりあえず、コントローラのテストを書いてみた。
public class HelloControllerTest
{
[TestClass] /* テスト対象群であることを表す */
public class Index /* テストしたいメソッド名 */
{
private HogeController controller;
[TestInitialize] /* テストの初期化処理毎。テスト毎に実行される */
public void TestInitialize()
{
// コントローラを初期化
this.controller = new HogeController();
// Indexアクションを実行する
var result = await this.controller.Index() as ActionResult;
}
[TestMethod] /* テスト対象 */
public async Task 一覧画面が表示されること()
{
// 結果オブジェクトがどうなっているかを確認する
result.IsInstanceOf<HogeResult>();
}
}
}
テストしやすいコード
とにかく DI (Dependency Injectyon) する
class HogeController
{
private IDependencyClass _Fuga { get; set; }
// 引数がないときは新しいインスタンスを注入する
public HogeController() : this(new DependencyClass()) { }
public HogeController(IDependencyClass fuga)
{
this._Fuga = fuga;
}
}
そうするとモックテストがはかどる
...
// Helloメソッドが"hello"を返すモックを作る
var mock = new Mock<IDependencyClass>();
mock.Setup(x => x.Hello()).Returns("hello");
// 作ったモックを注入したコントローラーをテストできる
var controller = new HogeController(mock.object);
var result = controller.Index() as ActionResult;
...
意識したいこと
- DI
- メソッドが利用しているクラスと結合しすぎてしまうため、インスタンスの生成処理は極力内部で行わない
- 他クラスを参照する場合は、DIで利用することを意識する
- DIモジュールをインタフェースで定義する
- 単一責任
- 一つのメソッドに色々な処理を含めず(ifでの分岐を減らす)、責任を一つにしてメソッドを分ける
- メソッド名と処理内容が一致しやすく読みやすくなる
- 担当の明確化
- Sessionやリクエストの状態はControllerに任せる(Model側に意識させない)
- ModelはDBと切り離しなるべくプレーンなクラスにする(POCO)。DBを意識させない
- Repositoryパターンを使うといい?かも
- ViewModelは表示に関する処理のみ記述する。値の生成などはModel側でやりたい
- Ruby on Rails的な思想
- DRY (Don't repeat yourself)
- 同じ処理は2度書かない
- レールに乗る (ベストプラクティスから外れないようにつくる)
- 他の人が読みやすいコードになる
- Rails程レールはないが、規約決めるといいかも
- DRY (Don't repeat yourself)
- 個人的な見解
- 性能より保守性
- LINQやEntityFrameworkを積極的に使いたい
- コードファースト
- Dbの構造のコード化
- DRYにもつながる
- 自動テストの利点
- 変更に強くなる
- コードが読みやすくなる
- Dbの構造のコード化
- 性能より保守性
その他
MSTestを全く触ったことがないので、他にもいいパッケージなど教えてほしいです...