COMオブジェクトのモック
-
08-07-2019 - |
質問
私は、文字列のみを受け取って返すことができるCOMオブジェクトのラッパーに取り組んできました。 COMオブジェクトのインターフェースは次のようになります。
interface IMapinfo
{
void Do(string cmd);
string Eval(string cmd);
}
次のように、基本的な機能をラップするクラスを作成しました。
public class Table
{
IMapinfo MI;
public string Name
{
//pass the command to the COM object and get back the name.
get{return MI.Eval("TableInfo(1,1")");}
}
}
今度は、実際のCOMオブジェクトを毎回作成せずに、これらのクラスで単体テストを行い、世界をセットアップしてからテストを実行します。そのため、モックオブジェクトの使用を検討してきましたが、この状況でモッキングを使用する方法について少し混乱しています。
Moqの使用を計画しているため、次のようにこのテストを作成しました。
[Test]
public void MockMapinfo()
{
Moq.Mock<Table> MockTable = new Moq.Mock<Table>();
MockTable.ExpectGet(n => n.Name)
.Returns("Water_Mains");
Table table = MockTable.Object;
var tablename = table.Name;
Assert.AreEqual("Water_Mains", tablename,string.Format("tablename is {0}",tablename));
Table d = new Table();
}
これは、COMオブジェクトをモックする正しい方法ですか? eval関数に送信される文字列が正しいことをどのように検証しますか?または私はそれをすべて間違っていますか?
解決
これは複製ですか? COM OLEオブジェクトでTDDを行う方法
編集:同じ質問をしているように見えますが、モックコード(OOPS)を検証します。
あなたは、あなたのモックのシナリオにはまったく向いていません。外部の依存関係を分離したいのはあなたです。COMオブジェクトは確かにその基準を満たしています。私はmoqの男ではありませんが(私はRhinoMocksが好きです)、mocksの背後にあるアイデアは相互作用テスト...
です。相互作用テストは、オブジェクトの凝集セットがどのように連携するかに関するものです。このシナリオで有効なテストは、COMオブジェクトの動作に依存するコンポーネントのテストを作成することです。
この場合、「テーブル」 COMオブジェクトのラッパーのように機能し、COMオブジェクトの動作にも依存します。引数のために、TableオブジェクトがCOMオブジェクトから返される値に対してカスタムロジックを実行するとします。
これで、モックを使用してCOMオブジェクトの動作をシミュレートしながら、Tableオブジェクトの分離テストを作成できます。
public class Table
{
public Table(IMapInfo map)
{
_map = map;
}
public string Name
{
get
{
string value = _map.Eval("myexpression");
if (String.IsNullOrEmpty(value))
{
value = "none";
}
return value;
}
}
private IMapInfo _map;
}
[TestFixture]
public class TableFixture // is this a pun?
{
[Test]
public void CanHandleNullsFromCOM()
{
MockRepository mocks = new MockRepository(); // rhino mocks, btw
IMapInfo map = mocks.CreateMock<IMapInfo>();
using (mocks.Record())
{
Expect.Call(map.Eval("myexpression").Return(null);
}
using (mocks.PlayBack())
{
Table table = new Table(map);
Assert.AreEqual("none", table.Name, "We didn't handle nulls correctly.");
}
mocks.verify();
}
}
COMオブジェクトが呼び出されたときに例外をスローするか、文字列式をうまく処理できない可能性があります。 COMオブジェクトの実装に縛られることなく、TableオブジェクトがIMapInfoと対話する方法を実際にテストしています。また、テスト中にIMapInfoオブジェクトを呼び出す必要があるという点で、TableとIMapInfoの関係を強制しています。
これがお役に立てば幸いです。