読者です 読者をやめる 読者になる 読者になる

無気力生活 (ノ ´ω`)ノ ~゜

脱力系エンジニア。てきとーに生きてます。

君はいいツールだったが、君のP-Invokeがいけないのだよ

「謀ったな・・・謀ったなTypwMock!!」
ただの戯言です、無視してやってください。


最近では主にC#使って開発をしているのですが、開発(特にテストコード)に最適なツールがあります。
Typemock Isolator 5.2.2
http://www.typemock.com/Downloads.php
シェアウェアですが、20日試用できます。
5.2は知りませんが、5.1まででは期限切れになっても再インストールすれば使えるようになります。

何をするツールかと申しますと、既存のメソッドを別のメソッドに置き換えることができるツールです。
メソッドの置き換え以外にも、戻り値を任意に指定できたりとかします。
たぶん内部で参照先のアドレスを差し替えたりしているのだと思われますが、詳しいことはわっかんね(´ω`)

説明だけじゃ分からないと思われるので軽くサンプルをば。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using TypeMock;

namespace TypeMockSample
{
 public partial class Form1 : Form
 {
  public Form1()
  {
   InitializeComponent();
  }

  private void Form1_Load(object sender, EventArgs e)
  {
   MockManager.Init();
  }

  private void button1_Click(object sender, EventArgs e)
  {
   this.ShowDialog_Hello();
  }

  private void button2_Click(object sender, EventArgs e)
  {
   Mock mock = MockManager.Mock(typeof(MessageBox), Constructor.NotMocked);
   mock.AlwaysReturn("Show", new DynamicReturnValue(this.ShowDialog_Hoge));
   this.ShowDialog_Hello();
   MockManager.Verify();
  }

  private void ShowDialog_Hello()
  {
   MessageBox.Show("Hello World!");
  }

  private object ShowDialog_Hoge(object[] parametors, object context)
  {
   return MessageBox.Show("Hoge hoge.");
  }
 }
}

まず、プロジェクトの参照設定に"TypeMock Isorator"を追加しちゃいましょう。
参照の追加ダイアログの.Netタブにいます。
参照追加後、TypeMockを使用したいソースファイルでusingします。

実装での注意点:
TypeMockを使う場合には、必ずMockManager.Init()メソッドを呼びましょう。
コンストラクタあたりで問題ないと思います。
使い終わった場合、MockManager.Verfty()を実行します。
このメソッドを実行することで、Mockのインスタンスを破棄し、メソッドの差し替えを解除します。

このサンプルでは、ボタン1押下時に"Hello World!"を表示しています。
ボタン2押下時には、System.Windows.Form.MessageクラスのShow()メソッドを、ShowDialog_Hoge()メソッドに差し替えています。
実行してみると、ボタン1押下時には"Hello World!"、ボタン2押下時には"Hoge hoge."と表示されます。

Expect〜と、Always〜の使い分けですが、
常に同じ処理に差し替えたいときはAlways、差し替えるメソッドを呼ばれるたびに変えたい、回数指定したいなどといった場合はExpectです。
ぶっちゃけ上二つしかわかんねーや('д`)
そもそもマニュアルが英語しかないってのがwww誰か日本語訳してください。


ただ、こいつも万能ではない模様
http://www.typemock.com/community/viewtopic.php?p=4632

>Unfortunately currently P-Invoke interoperability is not supported by Isolator.
残念ながら今のところ(TypeMock)IsolatorではP-Invoke相互運用はサポートしていません。
>I suggest you wrap the calls around the p-invoke with a managed method and fake it instead.
提案ですが、P-Invokeを呼び出す周辺の処理をマネージコードでラップし、そのメソッドに対してMockすることで目的が実現できます。
(注:しのゆ〜意訳)


もうちょっと研究が必要ですかね(´・ω・`)