在模拟 Excel.worksheet 时如何避免使用动态?

2024-04-24

我正在尝试使用 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 "";
}

最后一个有趣的部分是,如果我重新定义方法的签名,如下所示:
公共静态字符串 GetSetting(dynamic工作表,字符串设置名称)
它适用于 VSTO 项目。

那么到底发生了什么事,做这样的事情的最佳方法是什么?

Thanks!


VS2012更新: 起订量和互操作类型:在 VS2012 中有效,在 VS2010 中失败? https://stackoverflow.com/questions/13202120/moq-interop-types-works-in-vs2012-fails-in-vs2010

首先:有些事情发生了变化: 在模拟 Excel.worksheet 时如何避免使用动态? https://stackoverflow.com/questions/10843188/how-do-i-avoid-using-dynamic-when-mocking-an-excel-worksheet

我在使用 NSubstitute 模拟 Excel 对象时遇到了同样的问题。正如您提到的那样,动态解决了问题。但我想找到根本原因。


当您的项目引用了Microsoft.Office.Interop.Excel.Extensions.dll您需要检查嵌入互操作类型属性是否可见。如果是,则意味着您的目标是 .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 方面经历的所有悲伤thread https://stackoverflow.com/questions/9816243/mocked-object-doesnt-have-all-properties-shown-in-intellisense-in-one-project我认为使用 Mocking Frameworks 测试 VSTO .Net 4.0 项目是行不通的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在模拟 Excel.worksheet 时如何避免使用动态? 的相关文章

随机推荐

  • .Net Core 2.0 - 获取 AAD 访问令牌以与 Microsoft Graph 一起使用

    当使用 Azure AD 身份验证启动新的 Net Core 2 0 项目时 您将获得一个可以登录租户的工作示例 太棒了 现在我想获取登录用户的访问令牌并使用它来使用 Microsoft Graph API 我没有找到任何有关如何实现这一目
  • 在 odoo12 的表单视图中隐藏操作/更多按钮

    我想在 odoo12 中仅隐藏操作 更多按钮而不是打印按钮 我发现一些类似的问题在 odoo12 中不起作用 不是一个像样的答案 而是你的一个方向 源码中 我的版本是11 odoo 11 0 addons web static src js
  • 在分布式 dask 中,我们如何为每个工作人员选择 --nthreads 和 --nprocs ?

    我们如何选择 nthreads and nprocsDask 中每个工人的分布情况 我有 3 个工作线程 2 个工作线程有 4 个核心 每个核心有一个线程 1 个工作线程有 8 个核心 根据输出lscpu每个worker上的Linux命令
  • 如何将基数词转换为序数词

    有没有一种简单的方法可以将数字 1 2 3 转换为 1st 2nd 3rd 并且以这种方式我可以为该函数提供一种语言并具有它会返回我目标语言的正确形式吗 标准 C stl 或 boost 都可以 MFC 或 ATL win32 api 或我
  • 如何简洁地赋值并立即调用函数变量?

    以下是在闭包中定义匿名函数 调用该函数并忽略它的方法 function do stuff 这用于维持有限的范围而不向脚本添加大量内容 IIFE 立即调用函数表达式 如果您希望立即执行某个函数 同时仍保留该函数以供将来使用 该怎么办 如下所示
  • 在重新激活 WiFi/移动网络之前,服务中的 Android 位置侦听器无法工作

    我的位置侦听器工作正常 收集数据没有任何问题 但有时它不收集任何数据 我此时必须关闭并重新启动我的位置提供程序 重新启动可以解决问题 但是 这可能不是用户期望做的最好的事情 当我使用 GPS 作为提供商时 没有问题 位置侦听器在服务中工作
  • 在react-router-dom中隐藏某些页面的标题

    有没有办法可以仅隐藏 React Router 中某些路由的页面标题 我现在的问题是我的App组件呈现我的Main组件 其中包含我的BrowserRouter 和我的Header呈现在我的App组件 所以我无法根据路由路径渲染标题 这是一些
  • 如何从access中的表中获取选择性记录

    下面给出的是我的查询结果 但有很多冗余记录 因此 我想过滤掉这个查询的结果 我的目标是每个角度仅提取两个记录 第一个和最后一个 例如当角度为195 我想获得它的第一条记录日期 2 27 2017 时间 2 00 00 AM和 日期为的第二条
  • 禁用 Chrome 严格 MIME 类型检查

    有什么办法可以禁用strict MIME type checking在 Chrome 中 实际上我正在跨域发出 JSONP 请求 它在 Firefox 上工作正常 但是在使用 chrome 时 它 在控制台中出现一些错误 拒绝执行来自 的脚
  • 批处理文件随机删除文本文件的一半行?

    我需要一种方法来使用批处理来查看文本文件的每一行 并删除该文本文件中的一半行 随机选择要删除的行 这是为了模拟 D D 游戏中的锦标赛 我所需要的只是一种方法来淘汰每轮比赛的获胜者 我可以轻松地制作一个批处理文件 复制文本文件并为每一轮重命
  • Ionic 4:Cordova 不可用。确保包含 cordova.js 或在设备/模拟器中运行

    我正在尝试在新的 ionic 4 项目中使用 cordova 插件 但我总是遇到有关 cordova 的错误 该插件已正确安装并显示在插件文件夹中 Error 本机 尝试调用 SplashScreen hide 但 Cordova 不可用
  • 使用 ggplot 为长格式数据创建散点图

    我研究了一个长格式的 data frame 在每种情况下都有不同数量的实体 如下所示 Condition rating Control 2 1596456 Control 0 2385878 Control 3 0042808 Contro
  • 如何从下拉框中获取用户选择的值并将其添加到模型中? [复制]

    这个问题在这里已经有答案了 我有一个表单 用户在其中创建新考试 并在表单中用户从下拉菜单中选择一个主题 该下拉列表包含主题字符串 而不是实际的主题对象 在我的程序中 存在与考试具有一对多关系的实际主题对象 如何找到用户选择的值 我想将其添加
  • 配置 Sonar 以从 Maven pom.xml 中排除文件

    我有一个在maven中配置的项目 代码分析是由SonarQube完成的 我正在尝试在 pom xml 文件中配置 SonarQube 以从代码分析中排除一些文件 这些文件可以通过它们的类名来识别 它们在扩展名之前包含下划线字符 它们是元模型
  • 操作系统状态错误-50?

    我刚刚收到从 ExtAudioFileWrite 返回的结果代码 50 而我在 扩展音频文件服务参考 中并没有找到关于这个结果代码的信息 请帮我解决它 Thanks 该错误代码在CarbonCore框架的MacErrors h中声明 50
  • R-sqldf 错误原始与双精度

    我有一个矢量 lims 有分数限制 1 0 000000 7 025894 9 871630 12 411131 15 155998 18 099176 21 431354 25 391163 30 616550 40 356630 我创建
  • 如何使用 JAXB 从 xsd 生成实现 Serialized 接口的 Java 类?

    我想将缓存引入到现有的 Spring 项目中 该项目使用 JAXB 来公开 WebServices 缓存将在端点级别完成 为了做到这一点 使用 JAXB 从 XSD 生成的类需要实现Serializable接口和覆盖Object s toS
  • C# - Windows 窗体应用程序位图 SetPixel 和 GetPixel 的更快替代方案

    我正在尝试自学 C 并且从各种来源听说函数 get 和 setpixel 可能非常慢 有哪些替代方案 性能改进真的那么显着吗 我的一段代码供参考 public static Bitmap Paint Bitmap b Color f Bit
  • 客户端通过 websocket 连接从后端服务器数据库表检索数据

    我使用以下服务器代码从 postgres 数据库检索数据 const express require express const app express const server require http createServer app
  • 在模拟 Excel.worksheet 时如何避免使用动态?

    我正在尝试使用 NSubstitute 或其他模拟框架和 MSTest Visual Studio 2010 模拟 Excel 电子表格 我不确定是否有比这更好的方法 而且这对于测试来说不太有效 这是一个示例 这是目前的所有原型代码 并且不