10

NSubstitute またはその他のモック フレームワークと MSTest (Visual Studio 2010) を使用して Excel スプレッドシートをモックしようとしています。これよりも良い方法があるかどうかはわかりません-そして、これはテストにはうまくいきません:

以下に例を示します (これは現時点ではすべてプロトタイプ コードであり、あまりクリーンではありません)。

int[] lowerBounds = { 1, 1 };
int[] lengths = { 2, 2 };

//Initialize a 1-based array like Excel does:
object[,] values = (object[,])Array.CreateInstance(typeof(object), lengths, lowerBounds);
values[1,1] = "hello";
values[2,1] = "world";      

//Mock the UsedRange.Value2 property
sheet.UsedRange.Value2.Returns(values); 

//Test:   
GetSetting(sheet, "hello").Should().Be("world");  //FluentAssertions

GetSetting メソッドが私のテストと同じプロジェクトにある場合、これは合格です。ただし、GetSetting が VSTO Excel-Addin プロジェクトにある場合、GetSetting 関数の最初の行で次のエラーが発生して失敗します。

System.MissingMethodException: Error: Missing method 'instance object [MyExcel.AddIn] Microsoft.Office.Interop.Excel.Range::get_Value2()' from class 'Castle.Proxies.RangeProxy'.

参考までに、GetSetting はシートの列 A から値を取得し、列 B の値を返します。

public static string GetSetting(Excel.Worksheet sheet, string settingName) {
  object[,] value = sheet.UsedRange.Value2 as object[,];
  for (int row = 1; row <= value.GetLength(1); row++) {
    if (value[1, row].ToString() == settingName)
      return value[2, row].ToString();
  }
  return "";
}

最後の興味深い部分は、メソッドのシグネチャを次のように再定義した場合です:
public static string GetSetting( dynamic sheet, string settingName)
VSTO プロジェクトで機能します。

では、何が起こっているのでしょうか。また、このようなことを行う最善の方法は何ですか?

ありがとう!

4

2 に答える 2

5

VS2012 の更新: Moq & Interop の種類: VS2012 で動作し、VS2010 では失敗しますか?

最初に: 何かが変更されました: Excel.worksheet をモックするときに dynamic を使用しないようにするにはどうすればよいですか?

NSubstitute を使用して Excel オブジェクトをモックするという同じ問題が発生しました。あなたが言及したように、ダイナミックは問題を解決しました。しかし、私は根本的な原因を見つけたかったのです。


プロジェクトに への参照があるMicrosoft.Office.Interop.Excel.Extensions.dll場合、Embed Interop Types プロパティが表示されているかどうかを確認する必要があります。それがあなたのターゲティング.Net 4.0を意味する場合(動的キーワードから推測できます)。

.Net 4.0 を対象とするテスト プロジェクトをそのままにしておくことはできますが、VSTO プロジェクトの .Net フレームワークを 3.5 に戻す必要があります。次に、これらのエラーを取り除くために、明示的なキャストを行い、完全に修飾する必要があります。

C# Office Excel Interop の「オブジェクトに定義が含まれていません」というエラーが表示されます。いくつかの例を次に示します。

.Net 4.0:

if (tmpsheetName == xlApp.ActiveSheet.Name)

.Net 3.5 相当

Worksheet activeSheet = (Worksheet)xlApp.ActiveSheet;
if (tmpsheetName == activeSheet.Name)

もう一つの例:

rn.Select();

.Net 4.0

xlApp.Selection.HorizontalAlignment = Constants.xlCenter; 
xlApp.Selection.Font.Bold = true;
xlApp.Selection.Merge();

.Net 3.5 相当

rn.HorizontalAlignment = Constants.xlCenter;
rn.Font.Bold = true;
rn.Merge();

上記の例に従って、すべての .Net 3.5 と 4.0 の構文エラーの修正に進みます。dynamicパラメーターの型を削除して、元の型に置き換えることを忘れないでくださいWorksheet。最後に、もう一度テストを起動すると、パスします!!!

このスレッドで Microsoft.CSharp.DLL で経験したすべての悲しみを考えると、Mocking Frameworks を使用した VSTO .Net 4.0 プロジェクトのテストは機能しないという意見です。

于 2012-09-25T04:41:45.340 に答える
-1

城ベースのフレームワーク (nsubstitute、ninject など) を使用して、Excel オブジェクトや InDesign オブジェクトなどの非常に複雑な COM 相互運用オブジェクトをモックしても、十分なパフォーマンスが得られないことがわかりました。テストの実行時間は、依然として秒単位で測定可能です。(それを数十または数百のテストで乗算すると、単体テストはまだ遅すぎて、テストの TDD 原則の下で常に実行するには遅すぎます。)

次に、Excel ロジックのテストは統合テストと見なす必要があります。そのため、実際の Excel オブジェクトに対して実行しても問題ないため、そのようなシナリオではモックはあまり役に立ちません。結果は、実際のオブジェクトに対するテストよりもはるかに役立ちます。

Excel とアプリケーションの間に配置された抽象化レイヤーをテストすると、アプリケーション ロジックをすばやくテストできます。また、アプリケーションを徹底的にテストするには、統合テストの下で抽象化レイヤーから Excel までをテストするだけで十分です。

于 2012-08-20T18:47:25.097 に答える