1

我正在模拟 VSTO 对象,并且在一个项目中(我没有写)它具有以下代码:

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

mockSheets 的 Intellisense 工具提示显示 6 个属性:

N替换所有属性

带有断点的行在这个项目中有效。

但是,我在不同的项目中有相同的代码(相同的引用、命名空间等),但 mockSheets 的 Intellisense ToolTip 仅显示 1 个属性:

NSubstitute 只有一个属性

我知道这是我要解决的根本原因,但实际问题是:

无法对空引用执行运行时绑定

无法对空引用执行运行时绑定

编辑:

工作表对象被模拟:

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

这是一个疯狂的猜测,但 Office 互操作数组是基于 1 的,而不是基于 0 的。我还没有调查过,但这可能在元数据中定义。试试这个:

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

一些历史:

我遇到了这些错误的编译问题:

1.未定义或导入预定义类型“Microsoft.CSharp.RuntimeBinder.Binder” 2.找不到
编译动态表达式所需的一种或多种类型。您是否缺少对 Microsoft.CSharp.dll 和 System.Core.dll 的引用?

于是找到了这篇文章,并引用了Microsoft.CSharp库: C# 4.0 and .Net 3.5

直截了当: 我一直在展示的类本质上是模拟 Excel 对象模型,我将这个类从一个项目复制到另一个项目(我不能将另一个项目作为它实际独立的项目引用,而且它会导致循环依赖)我发现Returns 扩展方法在 intellisense 中列出,但编译时出现“无法解析符号”。即使在两个类/项目中去定义是相同的。为了解决这个问题,我最初做了注释掉的行:

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 对象具有其所有属性,并且能够成功执行而不会出现“无法在空引用上执行运行时绑定”错误。

哦,还有一个提示给任何人模拟互操作类型,设置这个要格外小心:

在此处输入图像描述

于 2012-03-23T01:07:32.660 回答
1

听起来可能是以下原因:

要测试的 VSTO 特定项目(插件/任务窗格/等)
VSTO 版本:VSTO 3.0 SP1
.NET 版本:.NET 3.5 SP1

上述项目的 VS 2010 测试项目
默认为
.NET 版本:.NET 4.0

这会在模拟对象时产生引用问题,因为测试项目期望能够使用 MS.Csharp(我猜)和可能的其他引用。

所以这个异常根本不是指mock对象返回的Null值,而是无法加载.NET 4.0的CSharp库导致的空绑定异常。

因此,正如您发现的那样,解决方案是删除 .net 4.0 Csharp 参考。尽管将项目设置为在 .net 3.5 下运行,但可能没有必要?不确定您是否必须测试是否出现任何其他问题。但我想如果可以的话,最好将测试项目保留在 .net 4 上。除非有人可以指出这是否不是最佳做法。

于 2012-03-23T03:13:15.520 回答
1

这是我每次编写 Nsubstitute Excel 单元测试时对自己的一个提醒。我已经与这个错误作斗争太多次了。

您将收到错误:无法对空引用执行运行时绑定

引用 .Net Excel 对象库后,必须引用 COM Microsoft Excel 14.0 对象库。引用 COM interop Excel DLL 后,单击 F4 以查看 DLL 属性,记住将 COM Interop NOT 设置为 Embed Interop Types。

.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 回答