1

私はVSTOオブジェクトをモックしています.1つのプロジェクト(私は書いていません)には次のコードがあります:

var listOfSheets = new List<Worksheet>();
var mockSheets = Substitute.For<Sheets>();
mockSheets.Count.Returns(listOfSheets.Count);

mockSheets の Intellisense ToolTip には、6 つのプロパティが表示されます。

NSubstitute すべてのプロパティ

このプロジェクトでは、ブレークポイントのある行が機能します。

ただし、別のプロジェクト (同じ参照、名前空間など) に同じコードがありますが、mockSheets の Intellisense ToolTip には 1 つのプロパティしか表示されません。

NSubstitute 1 つのプロパティのみ

これが解決しようとしている根本的な原因であることはわかっていますが、実際の問題は次のとおりです。

null 参照に対して実行時バインドを実行できません

null 参照に対して実行時バインドを実行できません

編集:

Sheet オブジェクトはモックされています。

public static Worksheet Sheet
{
    get
    {
        var mockSheet = Substitute.For<Worksheet>();
        mockSheet.Name = MockSheetName;
        mockSheet.Visible = XlSheetVisibility.xlSheetVisible;

        return mockSheet;
    }
}

public static Workbook Workbook()
{
    return Workbook(1);
}
4

4 に答える 4

1

いくつかの歴史:

これらのエラーでコンパイルの問題が発生していました:

1.事前定義されたタイプ'Microsoft.CSharp.RuntimeBinder.Binder'が定義またはインポートされていません
。2。動的式のコンパイルに必要な1つ以上のタイプが見つかりません。Microsoft.CSharp.dllおよびSystem.Core.dllへの参照がありませんか?

そこで、この記事を見つけて、Microsoft.CSharpライブラリ( C#4.0および.Net 3.5 )を参照しました。

要点: 私が示してきたクラスは基本的にExcelオブジェクトモデルをモックし、このクラスをあるプロジェクトから別のプロジェクトにコピーしました(実際には別のプロジェクトであり、循環依存を引き起こしたため、他のプロジェクトを参照することはできません)戻り値拡張メソッドはインテリセンスでリストされていましたが、コンパイル時に「シンボルを解決できませんでした」というメッセージが表示されました。定義に行くことは両方のクラス/プロジェクトで同じでしたが。これを回避するために、最初にコメントアウトした行を実行しました。

public static Range Cell
{
    get
    {
        var mockCell = Substitute.For<Range>();
        mockCell.Address.Returns("$A$1");
        mockCell.Formula = "=1+1";
        mockCell.ToString().Returns(mockCell.Formula.ToString());
        //mockCell.ToString().Returns(info => mockCell.Formula.ToString());
        //SubstituteExtensions.Returns(mockCell.ToString(),  mockCell.Formula.ToString());
        mockCell.Worksheet.Returns(Sheet);
        mockCell.Worksheet.Name.Returns(MockSheetName);

        return mockCell;
    }
}

この点は少し厄介ですが、Microsoft.CSharp dllを削除すると、Returns拡張メソッドを実際に正常に解決できました。次に、Microsoft.CSharp dllを削除すると問題が解決したことがわかりました。すべて正常に機能し、mockSheetオブジェクトにはすべてのプロパティがあり、「null参照でランタイムバインディングを実行できません」というエラーなしで正常に実行できました。

ああ、相互運用タイプをモックする人のためのヒントです。これを設定する場合は特に注意してください。

ここに画像の説明を入力してください

于 2012-03-23T01:07:32.660 に答える
1

原因として次のことが考えられます。

テストする VSTO 固有のプロジェクト (アドイン/タスクペイン/etc)
VSTO バージョン: VSTO 3.0 SP1
.NET バージョン: .NET 3.5 SP1

上記のプロジェクトの VS 2010 テスト プロジェクトの
デフォルトは
.NET Ver: .NET 4.0

これは、テスト プロジェクトが MS.Csharp (推測) やその他の参照を使用できることを期待しているため、オブジェクトをモックアップするときに参照の問題を引き起こす可能性があります。

したがって、例外は実際にはモック オブジェクトによって返された Null 値をまったく参照しているのではなく、.NET 4.0 の CSharp ライブラリを読み込めないために発生した null バインディング例外です。

したがって、解決策は.net 4.0 Csharp参照を削除することです。プロジェクトを .net 3.5 で実行するように設定する必要はありませんか? 他の問題が発生したかどうかをテストする必要があるかどうかはわかりません。しかし、可能であれば、テスト プロジェクトを .net 4 に保持した方がよいと思います。これがベストプラクティスではないかどうかを誰かが示すことができない限り。

于 2012-03-23T03:13:15.520 に答える
1

これは大雑把な推測ですが、Office Interop アレイは 0 ベースではなく 1 ベースです。調べたことはありませんが、これはメタデータで定義されている可能性があります。これを試して:

for (int i = 0; i < numSheets; i++)
{
    listOfSheets.Add(Sheet);
    listOfSheets[i].Name = MockSheetName + (i + 1);
    `mockSheets[i + 1].Returns(listOfSheets[i]);`
}
于 2012-03-22T06:50:27.570 に答える
1

これは、Nsubstitute Excel Unit Tests を書くたびに、自分自身に思い出させるものです。私は何度もこのエラーと戦ってきました。

次のエラーが表示されます: null 参照でランタイム バインディングを実行できません

.Net Excel オブジェクト ライブラリを参照した場合は、COM Microsoft Excel 14.0 オブジェクト ライブラリを参照する必要があります。COM 相互運用 Excel DLL が参照されたら、F4 をクリックして DLL のプロパティを表示します。COM 相互運用を [相互運用型を埋め込む] に設定しないでください。

.Excel 作業中のプロジェクト ファイルは次のとおりです。

<ItemGroup>
    <Reference Include="Microsoft.Office.Interop.Excel.Extensions">
      <HintPath>..\..\Refs\Microsoft.Office.Interop.Excel.Extensions.dll</HintPath>
    </Reference>
    <Reference Include="Microsoft.VisualStudio.QualityTools.UnitTestFramework, Version=10.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" />
    <Reference Include="NSubstitute">
      <HintPath>..\..\Refs\NSubstitute.dll</HintPath>
    </Reference>
    <Reference Include="System" />
    <Reference Include="System.Core">
      <RequiredTargetFramework>3.5</RequiredTargetFramework>
    </Reference>
    <Reference Include="System.Data" />
    <Reference Include="System.Data.DataSetExtensions" />
    <Reference Include="System.Runtime.Serialization" />
    <Reference Include="System.Xml" />
    <Reference Include="System.Xml.Linq" />
    <Reference Include="UIAutomationProvider" />
    <Reference Include="VSTOContrib.Core, Version=0.9.0.52, Culture=neutral, processorArchitecture=MSIL" />
    <Reference Include="WindowsBase" />
    <Reference Include="WindowsFormsIntegration" />
  </ItemGroup>
  <ItemGroup>
    <CodeAnalysisDependentAssemblyPaths Condition=" '$(VS100COMNTOOLS)' != '' " Include="$(VS100COMNTOOLS)..\IDE\PrivateAssemblies">
      <Visible>False</Visible>
    </CodeAnalysisDependentAssemblyPaths>
  </ItemGroup>
  <ItemGroup>
    <Compile Include="MockFactory.cs" />
    <Compile Include="Properties\AssemblyInfo.cs" />
    <Compile Include="UnitTests.cs" />
  </ItemGroup>
  <ItemGroup>
      <COMReference Include="Microsoft.Office.Core">
      <Guid>{2DF8D04C-5BFA-101B-BDE5-00AA0044DE52}</Guid>
      <VersionMajor>2</VersionMajor>
      <VersionMinor>4</VersionMinor>
      <Lcid>0</Lcid>
      <WrapperTool>primary</WrapperTool>
      <Isolated>False</Isolated>
    </COMReference>
    <COMReference Include="Microsoft.Office.Interop.Excel">
      <Guid>{00020813-0000-0000-C000-000000000046}</Guid>
      <VersionMajor>1</VersionMajor>
      <VersionMinor>6</VersionMinor>
      <Lcid>0</Lcid>
      <WrapperTool>primary</WrapperTool>
      <Isolated>False</Isolated>
    </COMReference>
  </ItemGroup>

問題は、この .Net Interop リファレンスです (COM リファレンスである必要があります)。

<Reference Include="Microsoft.Office.Interop.Excel, Version=14.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c, processorArchitecture=MSIL">
  <EmbedInteropTypes>True</EmbedInteropTypes>
</Reference>
于 2012-08-21T00:45:13.257 に答える