まさるblog

越後在住子持ちプログラマー奮闘記 - Author:まさる(高野 将、TAKANO Sho)

目次

Blog 利用状況

ニュース

著書

2010/7発売


Web掲載記事

@IT

.NET開発を始めるVB6プログラマーが知るべき9のこと

CodeZine

実例で学ぶASP.NET Webフォーム業務アプリケーション開発のポイント

第1回 3層データバインドを正しく活用しよう(前編)

ブログパーツ


書庫

日記カテゴリ

コミュニティ

Moq探訪~その2~:Mockライブラリを使うと何が嬉しいのか

Moq探訪~その1~:Moqとは何か?Mockとは何か?そしてMockの生成 #adcjcsに続く第2回目。

 

前回はMockとは何か?Moqとは何か?Moqを使ったMockオブジェクトの作成方法について紹介しました。

今回は、先に進む前になぜMockライブラリを使うのか、という話をしようと思います。

 

従来のMockオブジェクト作成方法

今のように便利なMockライブラリができる前も、「Mock」という考えはありました。その実現方法は、

サブクラス化して、それぞれのメソッドをオーバーライドする

または

interfaceを実装し、それぞれのメソッドを記述する

というものでした。

 

例を次に示します。

・Mock対象interface

public interface IMyInterface
{
  void doSomething();
}

 

・Mockクラス

public class MyMock : IMyInterface
{
  public void doSomething()
  {
    // 偽装した処理
  }
}

 

・Mockの使用方法

class Program
{
  static void Main(string[] args)
  {
    // Mockオブジェクトの作成
    var mock = new MyMock();

    // Mockの使用
    mock.doSomething();
  }
}

 

従来の方法の問題

サブクラスまたは実装クラスを使ってMockを作成する方法には、大きく2つの問題があります。

  1. Mock対象のメソッドが多い場合、Mockクラスのコードが膨大になる。
  2. 偽装したい処理ごとにいくつもMockクラスを作る必要がある。

 

1.巨大なMockコード

上で説明したような、メソッドが1つだけのようなinterfaceなら良いのですが、多くのメソッドを持つinterfaceを偽装する場合、そのすべてのメソッドを実装しなければなりません。

したがって、偽装したいメソッド以外にも、余計なコードが必要です。

 

以下に、IListインターフェースの例を示します。

public class MyList : IList
{

  public int Add(object value)
  {
    return 0;
  }

  public void Clear()
  {
  }

  public bool Contains(object value)
  {
    return false;
  }

  public int IndexOf(object value)
  {
    return 0;
  }

  public void Insert(int index, object value)
  {
  }

  public bool IsFixedSize
  {
    get { return true; }
  }

  public bool IsReadOnly
  {
    get { return true; }
  }

  public void Remove(object value)
  {
  }

  public void RemoveAt(int index)
  {
  }

  private object[] objects;
  public object this[int index]
  {
    get
    {
      return objects[index];
    }
    set
    {
      objects[index] = value;
    }
  }

  public void CopyTo(Array array, int index)
  {
  }

  // このプロパティだけ偽装したい
  public int Count
  {
    get { return 0; }
  }

  public bool IsSynchronized
  {
    get { return false; }
  }

  public object SyncRoot
  {
    get { return null; }
  }

  public IEnumerator GetEnumerator()
  {
    return objects.GetEnumerator();
  }
}

2.複数のMockクラスが必要

偽装したい処理が少なければまだよいのですが、0を返す場合、1を返す場合、例外を発生させる場合、・・・と様々な処理を偽装したい場合、その処理ごとにMockクラスを作成する必要があります。

 

以下に例を示します。

・Mock対象inteface

public interface IMyInterface
{
  int GetCount();
}

 

・Mockクラス

// 0を返すMock
public class MyMockReturnZero : IMyInterface
{
  public int GetCount()
  {
    return 0;
  }
}

// 1を返すMock
public class MyMockReturnOne : IMyInterface
{
  public int GetCount()
  {
    return 1;
  }
}

// 例外をthrowするMock
public class MyMockThrowException : IMyInterface
{
  public int GetCount()
  {
    throw new Exception("例外処理の偽装");
  }
}

 

Mockライブラリを使った解決

Mockライブラリを使うと、上記の問題を解決し、コード量を大幅に削減することができます。

 

1.Mockオブジェクト専用の実装クラスが不要

前回紹介したように、Moqを使ってMockオブジェクトを作成するには、これだけです。

// Mockの作成
var mock = new Mock<IMyInterface>();

// Mockオブジェクトの取得
var obj = mock.Object;

 

2.複数の処理を偽装したMockの作成が容易

Moqを使って複数の処理を偽装するには、次のように書きます。

 

・Mock作成コード

public static void Main(string[] args)
{
  // Mockの作成
  var mock = new Mock<IMyInterface>();

  // 0を返す
  mock.Setup(m => m.GetCount()).Returns(0);
  Console.WriteLine(mock.Object.GetCount());

  // 1を返す
  mock.Setup(m => m.GetCount()).Returns(1);
  Console.WriteLine(mock.Object.GetCount());

  // 例外を発生させる
  mock.Setup(m => m.GetCount()).Throws(new Exception("例外を発生させる"));
  try
  {
    mock.Object.GetCount();
  }
  catch (Exception ex)
  {
    Console.WriteLine(ex);
  }
}

・実行結果

image

 

まとめ

  • MockライブラリがなくてもMockを作成することは可能。
    • ただし、かなりコード量が多くなる。
  • Mockライブラリを使うことで、シンプルにMockを記述できるようになる。
    • コード量を大幅に削減できる。

 

次回以降の予定

Mockライブラリの利点を紹介したところで、次からは実際にいろいろなMoqの機能を紹介していきます。

投稿日時 : 2010年12月6日 5:52

Feedback

# re: Moq探訪~その2~:Mockライブラリを使うと何が嬉しいのか 2010/12/07 9:15 bleis-tift

「2.複数のMockクラスが必要」ですが、
setter を使って期待値を設定する方式が普通かな、と思います。

public class MyMock : IMyInterface
{
internal MyMock()
{
CountImple = () => 0;
}

internal Func<int> CountImpl { get; set; }
public int GetCount()
{
return Count();
}
}

# Hey, that's pworeful. Thanks for the news. 2012/01/27 20:43 Denisha

Hey, that's pworeful. Thanks for the news.

# Hey, that's pworeful. Thanks for the news. 2012/01/27 20:43 Denisha

Hey, that's pworeful. Thanks for the news.

# Hey, that's pworeful. Thanks for the news. 2012/01/27 20:43 Denisha

Hey, that's pworeful. Thanks for the news.

# http://www.fivu.cn
2016/11/02 22:10 carpinteyrokim

http://www.kleid.us/Tags/E.html

# It's hard to come by knowledgeable people on this subject, but you seem like you know what you're talking about! Thanks 2019/04/10 7:56 It's hard to come by knowledgeable people on this

It's hard to come by knowledgeable people on this subject,
but you seem like you know what you're talking about! Thanks

# I am really enjoying the theme/design of your website. Do you ever run into any web browser compatibility issues? A number of my blog readers have complained about my blog not operating correctly in Explorer but looks great in Chrome. Do you have any sug 2019/07/16 16:12 I am really enjoying the theme/design of your webs

I am really enjoying the theme/design of your website.
Do you ever run into any web browser compatibility issues?
A number of my blog readers have complained about my blog not operating correctly in Explorer but
looks great in Chrome. Do you have any suggestions to help fix this
problem?

# It's perfect time to make some plans for the long run and it is time to be happy. I have learn this submit and if I may I wish to suggest you some fascinating things or tips. Perhaps you could write subsequent articles referring to this article. I want 2019/07/18 4:30 It's perfect time to make some plans for the long

It's perfect time to make some plans for the long run and it is time to be happy.

I have learn this submit and if I may I wish to suggest you some fascinating
things or tips. Perhaps you could write subsequent articles referring to this article.
I want to learn more issues about it!

# It's perfect time to make some plans for the long run and it is time to be happy. I have learn this submit and if I may I wish to suggest you some fascinating things or tips. Perhaps you could write subsequent articles referring to this article. I want 2019/07/18 4:31 It's perfect time to make some plans for the long

It's perfect time to make some plans for the long run and it is time to be happy.

I have learn this submit and if I may I wish to suggest you some fascinating
things or tips. Perhaps you could write subsequent articles referring to this article.
I want to learn more issues about it!

# It's perfect time to make some plans for the long run and it is time to be happy. I have learn this submit and if I may I wish to suggest you some fascinating things or tips. Perhaps you could write subsequent articles referring to this article. I want 2019/07/18 4:32 It's perfect time to make some plans for the long

It's perfect time to make some plans for the long run and it is time to be happy.

I have learn this submit and if I may I wish to suggest you some fascinating
things or tips. Perhaps you could write subsequent articles referring to this article.
I want to learn more issues about it!

# It's perfect time to make some plans for the long run and it is time to be happy. I have learn this submit and if I may I wish to suggest you some fascinating things or tips. Perhaps you could write subsequent articles referring to this article. I want 2019/07/18 4:33 It's perfect time to make some plans for the long

It's perfect time to make some plans for the long run and it is time to be happy.

I have learn this submit and if I may I wish to suggest you some fascinating
things or tips. Perhaps you could write subsequent articles referring to this article.
I want to learn more issues about it!

# Why visitors still make use of to read news papers when in this technological globe everything is presented on net? 2019/09/02 9:14 Why visitors still make use of to read news papers

Why visitors still make use of to read news papers when in this technological globe everything is presented on net?

# re: Moq??~??2~:Mock???????????????? 2021/08/07 2:40 hydroxychloriqine

is chloroquine available over the counter https://chloroquineorigin.com/# lupus wikipedia english

# oibsqugfgxld 2022/06/03 13:55 wkegjklf

erythromycin base 250mg http://erythromycin1m.com/#

タイトル
名前
Url
コメント