約500の単体テストを含む.NETライブラリプロジェクトがあります。これらのテストはすべてVisualStudio2012で正常に実行されます。ただし、一部のテストはVisual Studio 2010で失敗します。これらの失敗したテストでは、Moqを使用してからいくつかの相互運用機能タイプをモックしMicrosoft.Office.Interop.Excel
ます。これらのモックされた相互運用タイプにアクセスしようとすると、テストはすぐに失敗します。
Error: Missing method 'instance class Microsoft.Office.Interop.Excel.Range [ExcelAddIn.Core] Microsoft.Office.Interop.Excel.ListRow::get_Range()' from class 'Castle.Proxies.ListRowProxy'.
この例外は、モックに適切なプロパティゲッターを設定するのを忘れたことを意味します。そうではありません:
_listRowMock.Setup(m => m.Range).Returns(_rangeMock.Object);
これで、Moqが相互運用タイプではうまく機能しない可能性があることが想像できます。しかし、私が最も困惑しているのは、これらのテストはVisual Studio 2012では正常に実行されますが、VisualStudio2010では失敗することです。
Visual Studioがコードの動作に影響を与えるのはなぜですか?
更新:2012年3月11日
わかりました、それで私はこれにそれを理解しました:
- 私には2つのプロジェクトがあります。CoreおよびCore.UnitTest。Coreは実際のライブラリであり、Core.UnitTestはCoreライブラリの単体テストプロジェクトです。
- どちらのプロジェクトも、埋め込み相互運用機能が有効になっているMicrosoft.Office.Interop.Excelを参照しています。
- EITが有効になっているため、どちらのプロジェクトにもMicrosoft.Office.Interop.Excelライブラリの独自の「ビュー」が含まれています。ビューには、それぞれのプロジェクトで使用されるすべてのクラス、メソッド、およびプロパティが含まれます。
- 両方のプロジェクトがMicrosoft.Office.Interop.Excelの異なるクラス、メソッド、およびプロパティを使用するため、両方のライブラリの埋め込みタイプは異なります。たとえば、CoreのListRowにはIndexプロパティとRangeプロパティがありますが、Core.UnitTestのListRowにはRangeプロパティしかありません。
- どちらのタイプも異なり、共通のインターフェイスやスーパークラスを共有していませんが、同等です。これは、CLRがそれらを同じものとして扱い、アセンブリの境界を越えてこれらのタイプを使用できるようにすることを意味します。たとえば、Core.UnitTestのListRowのインスタンスは、コアライブラリのメソッドに渡されたときに正常に機能します。共有のRangeプロパティは機能しますが、欠落しているIndexプロパティは、アクセス時にMissingMethodExceptionをスローします。
- 前述の動作は、モックされたタイプでも機能します。Mock [Excel.ListRow]のモックオブジェクトは、アセンブリの境界を越えるときに正常に機能します。
- 残念ながら、前のポイントで説明した動作は、VisualStudio2012でアセンブリをビルドする場合にのみ機能します。Visual Studio 2010でアセンブリをビルドしてコードをデバッグすると、モックされたListRowインスタンスがコアプロジェクトのメソッドに渡されていることがわかります。インスタンスがアセンブリの境界を越えると、ListRowのすべてのメソッドとプロパティが実装を失い、MissingMethodExceptionsをスローします。
- 楽しい部分として、私は実際に、両方の埋め込みタイプのListRowが整列されていることを確認することで、この問題を軽減することができました。たとえば、コンパイラが両方のプロジェクトでListRowの同じビューを作成するために、UnitTestプロジェクトでまったく同じメソッドとプロパティを使用していることを確認しました。これは、var dump=listRow.Indexのようなダミー行を追加することを意味します。コンパイラに埋め込みListRowタイプの同一のビューを作成させると、インスタンスはその実装を失うことなくアセンブリの境界を越えることができました。
ただし、まだ疑問が残ります。VisualStudio2010とVisualStudio 2012の動作にこの違いが生じる原因は何ですか?
更新:2012年9月11日
デモソリューション:http ://temp-share.com/show/KdPf6066h
効果を実証するための小さなソリューションを作成しました。このソリューションは、ライブラリとUnitTestプロジェクトで構成されています。どちらも、EITが有効になっているMicrosoft.Office.Interop.Excel.Rangeを参照しています。テストはVS2012で正常に機能しますが、VS2010ではMissingMethodExceptionをスローします。テストでダミー行のコメントを解除すると、VS2010で機能するようになります。
最終更新:2012年12月29日
更新が遅れたことをお詫びします。同僚が解決策を見つけましたが、自分のマシンでそれを再現することができませんでした。その間に、当社はTFS2012に切り替えたので、これは私にとってもはやブロッキングの問題ではありません。私の同僚が行った2つの最も重要な結論は次のとおりです。
- 「任意のCPU」プラットフォームのセマンティクスがVisualStudio2010からVisualStudio2012に変更されました。これにより、VS2010とVS2012のどちらを使用しているかに応じて、異なる.DLLが生成されます。
- どちらのプロジェクトも、異なるバージョンのMicrosoft.Office.Interop.Excelを参照していました。
私は自分のプロジェクトをチェックし、参照を整理しましたが、違いはありませんでした。その後、VS2010とVS2012の両方でプラットフォームのさまざまなバリエーションを試しましたが、満足のいく結果を得ることができませんでした。ジェレミーの答えが最も役に立ったので、私はそれを受け入れます。皆様のご協力に感謝いたします。