如何访问另一个程序集中的类以进行单元测试?

Posted

技术标签:

【中文标题】如何访问另一个程序集中的类以进行单元测试?【英文标题】:How to access classes in another assembly for unit-testing purposes? 【发布时间】:2010-11-15 18:01:54 【问题描述】:

我正在以 Visual-Studio 2008 的方式进行单元测试,我想知道什么是完成交叉组装class 访问以进行测试的最佳方式。

基本上,我在一个解决方案中有两个项目:

    我的项目 (C#) MyProjectTests(C# 测试项目)

MyProject 中的所有内容当前都具有默认可访问性,如果我没记错的话,这意味着所有内容实际上都是internal。我主要希望在class 级别进行测试,但也有一些delegates 参与其中。

未来某个时候可能会有一个外部 API,但我已经完成了大约 20% 的功能(至少在纸面上),而且我对在这个未经测试的基础上分层更多代码持谨慎态度核。因此,我现在想在应用程序完成到足以进行传统(阅读:坏和/或懒惰)功能测试之前完成一些测试,并且肯定在版本 n+1 外部 API 发布之前完成。

除了直截了当的答案外,我们将非常感谢您提供解决方案的示例。

【问题讨论】:

为了避免您的下一个问题——如果测试程序集已签名,为什么必须对测试程序集进行签名? -- 这是我关于该主题的文章:blogs.msdn.com/ericlippert/archive/2009/06/04/… 【参考方案1】:

您可以使用程序集级属性InternalsVisibleToAttribute 来实现这一点。

添加

[assembly:InternalsVisibleTo("MyProjectTests")]

到您的 MyProject 程序集中的 AssemblyInfo.cs。

【讨论】:

当然,包括适当的强名称键引用——你是强命名你的程序集,不是吗。【参考方案2】:

你需要添加

[assembly:InternalsVisibleTo("Unit.Tests.Assembly")] 

到您的“MyProject (C#)”的 AssemblyInfo.cs。然后,您的测试就可以访问内部测试方法。

【讨论】:

【参考方案3】:

您可以通过向主项目的 AssemblyInfo.cs 添加属性来测试内部方法,从而可以访问命名程序集的内部方法:

[程序集:InternalsVisibleTo("MyProjectTestsNameSpace.MyProjectTests")]

更多信息是here

【讨论】:

链接已损坏 :(【参考方案4】:

看来您需要InternalsVisibleToAttribute

但我建议不要使用这种方法 - 通过公共接口或 API 测试您的内部类。

【讨论】:

问题是那些还不存在;并且暂时不会。这是一个大型项目(或者,它会在完成时)。 由内而外方法的问题在于,您可能会遇到这样一种情况:您已经完成了内部操作。但外部 API 没有按预期插入 - 因为理解上存在脱节。反馈要晚得多......当纠正成本更高时。 没错,但是在应用程序“完成”之前推迟全面测试只是在自找麻烦。此外,外部 API 可能会采取自动化用户操作和提取数据的形式,而不是扩展功能;与完整的插件 API 相比,它更难搞砸。 我不提倡直到最后才进行测试。我的意思是从外向内形成薄的垂直切片。但是,您更了解您的具体情况 - 如果风险很小,它没关系。【参考方案5】:

虽然[InternalsVisibleTo] 是 IMO 最明智的方式,但至少还有 2 种其他方式可以解决这个问题:

通过使用Reflection

 var method = instance.GetType().GetMethod(
    methodName, BindingFlags.NonPublic | BindingFlags.Instance, 
    null, paramTypeArray, null);
 return method.Invoke(instance, parameters);

这种方法的问题在于,如果方法名称或签名发生更改,单元测试将在运行时开始失败,而 [InternalsVisibleTo] 很容易在编译时发现这一重大更改。

使用像Moles / FakesTypeMock 这样的测试框架

【讨论】:

【参考方案6】:

我找到了这个https://msdn.microsoft.com/en-us/library/hh598957.aspx希望它可以帮助某人。

总结:

在您的单元测试项目中,添加对被测代码的引用。以下是如何在同一解决方案中创建对代码项目的引用: 在解决方案资源管理器中选择项目。 在“项目”菜单上,选择“添加引用...”。 在“参考管理器”对话框中,打开“解决方案”节点并选择“项目”。 检查代码项目名称并关闭对话框。

【讨论】:

以上是关于如何访问另一个程序集中的类以进行单元测试?的主要内容,如果未能解决你的问题,请参考以下文章

如何从另一个模块访问测试类以在 junit 测试中使用?

如何指定多个项目的 InternalsVisibleTo

我应该对数据访问层进行单元测试吗?这是一个好习惯以及如何去做?

如何对一个扩展了抽象类的类进行单元测试,读取环境变量。

如何对 PHP 特征进行单元测试

如何对扩展/继承第 3 方类的类进行单元测试