23
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ASP.NET MVCのユニットテストを実装するときに考えたこと

Last updated at Posted at 2016-02-07

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程レールはないが、規約決めるといいかも
  • 個人的な見解
    • 性能より保守性
      • LINQやEntityFrameworkを積極的に使いたい
    • コードファースト
      • Dbの構造のコード化
        • DRYにもつながる
      • 自動テストの利点
        • 変更に強くなる
        • コードが読みやすくなる

その他

MSTestを全く触ったことがないので、他にもいいパッケージなど教えてほしいです...

23
31
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
23
31

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?