Making code internal but available for unit testing from other projects
我们将所有单元测试都放在他们自己的项目中。 我们发现我们必须将某些类公开而不是内部仅用于单元测试。 无论如何都要避免这样做。 通过将类公开而不是密封来实现内存含义是什么?
-
在进行单元测试时可能重复使用C#"internal"访问修饰符
如果您使用的是.NET,则InternalsVisibleTo程序集属性允许您创建"朋友"程序集。这些是特定的强名称程序集,允许访问内部类和其他程序集的成员。
请注意,这应该谨慎使用,因为它紧密耦合相关的组件。 InternalsVisibleTo的常见用途是用于单元测试项目。由于上述原因,它可能不适合在您的实际应用程序集中使用。
例:
1 2 3
| [assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{ |
-
谢谢!这绝对应该是公认的答案。
-
我建议在属性周围加一个#if DEBUG,然后在debug中进行单元测试。这样你就可以确保该属性不是在发布代码上设置的。
-
这只是一个想法,我不知道....怎么样:#if DEBUG公共类IniReader #else内部类IniReader #endif可能不推荐?为什么?
-
那么,为什么限制测试来调试构建呢?
-
此外,只是一个挑剔,没有必要强烈命名"朋友"集会(可能是一个很好的做法 - 即使我个人的口味否则,但不是强制性的)。
-
不同意。 如果我使用非常薄的公共API构建复杂组件,那么仅通过公共API进行测试是不切实际且不切实际的。 你最终会得到一个无法维持的泥球。 相反,我会仔细定义内部单元并单独测试它们。 正如杰里米·D·米勒(Jeremy D. Miller)经常说的那样:"在你考试之前测试一下"。
-
对于.NET Core - 将InternalsVisibleTo添加到应用程序中的任何.cs文件。 请在此处查看详细信息 - stackoverflow.com/a/42235577/968003
-
虽然这在单元测试中实际上是什么样的?
如果它是一个内部类,那么它不能被孤立地使用。因此,除了测试在内部使用该对象的其他类之外,您不应该真正测试它。
正如您不应该测试类的私有成员一样,您不应该测试DLL的内部类。这些类是一些可公开访问的类的实现细节,因此应该通过其他单元测试来很好地执行。
这个想法是你只想测试一个类的行为,因为如果你测试内部实现细节,那么你的测试将是脆弱的。您应该能够在不破坏所有测试的情况下更改任何类的实现细节。
如果您发现确实需要测试该类,那么您可能想要首先重新检查该类为什么是内部的。
-
实施细节应作为包含测试的一部分进行。不要偷看私有变量......测试预期的行为。如果测试正确..所有内部管道和接线都应作为其一部分进行测试。投票了。
-
我不一定同意这一点,因为这些类对DLL内的其他类是"公开的",并且该类的功能应该是独立测试的
-
我也不同意。单位是单位,必须单独测试。
-
伟大的一般准则,但让我们不要教条。测试有两个主要目的:1)回归 - 确保你没有破坏某些东西,2)提高开发速度。如果每次我想编写一行代码时我都必须提供大量服务,那么我将阻碍开发。如果我有一个复杂的内部部分,我希望能够孤立地开发和测试。相反,我不希望所有测试都被隔离(因此降低了回归测试值,或重复测试代码),但有些代码证明了隔离。也许关键是要使它成为一个单独的组件。
-
我的类是内部的,因为它是作为nuget程序集分发的开放库的一部分 - 它有一个可用类的公共API,我希望内部使用的类是"内部的"。不确定我需要如何重新检查 - 这些类需要进行测试。对于那些理解"可用"(即不是内部)的人来说,他们不是公开的服务。你基本上是说不应该测试API的私有部分 - 听起来对我不对
-
@PandaWood - 绝对不是。我主张强大的测试覆盖率,但根据定义,API的那些私有部分应该进行测试,因为它们用于支持公共API。对公共API进行充分测试将运行私有成员,如果没有,则会有不必要的代码。
-
@Josh那将是集成测试。内部类仍然需要单元测试。我的情况与测试私有类成员不同,因为我的类只是作为代码消费者的澄清而"内部",并且避免向他们提供他们没有/不能/不应该使用的类
-
OP在这里是正确的。您将测试与内部实现相结合。因此,您的团队永远是修补测试和可怕的模拟代码的奴隶。仅测试公共API,即打包的lib API或网络公开的API。所有代码都应通过前门行使。测试实现是TDD在很大程度上已经死亡的原因,它只是一个巨大的PITA来测试整个应用程序的每个类,而不是专注于确保系统的行为。我想几乎每个人,包括"权威"书籍,都有这个错误或没有说清楚。
-
如果您无法通过公共类和方法测试FULLY,则访问内部类和方法会导致测试覆盖率不佳。考虑在你的代码中运送测试类,测试可以用来挂钩内部代码,这不太理想...但是可靠的电视里面有JTAG连接器,可靠的汽车里面有一个诊断端口,它的常识 - 但是不要用它来驱动车!
-
我认为这个答案虽然有用,但可以就如何解决这个问题提出更多建议
用于文档目的
或者,您可以使用Type.GetType方法实例化内部类
例
1 2 3 4 5 6 7
| //IServiceWrapper is public class which is
//the same assembly with the internal class
var asm = typeof(IServiceWrapper ).Assembly;
//Namespace.ServiceWrapper is internal
var type = asm .GetType("Namespace.ServiceWrapper");
return (IServiceWrapper < T >)Activator
.CreateInstance(type, new object[1] { /*constructor parameter*/ }); |
对于泛型类型,有不同的过程如下:
1 2 3 4 5 6 7
| var asm = typeof(IServiceWrapper ).Assembly;
//note the name Namespace.ServiceWrapper`1
//this is for calling Namespace.ServiceWrapper<>
var type = asm .GetType("Namespace.ServiceWrapper`1");
var genType = type .MakeGenericType(new Type [1] { typeof(T ) });
return (IServiceWrapper < T >)Activator
.CreateInstance(genType, new object[1] { /*constructor parameter*/}); |
课程既可以公开也可以密封。
但是,不要这样做。
您可以创建一个工具来反映内部类,并发出一个通过反射访问所有内容的新类。 MSTest做到了。
编辑:我的意思是,如果您不想在原始程序集中包含-any-测试内容;如果成员是私人的,这也有效。
-
等等,什么?你说不要做public sealed class?你对这颗宝石的理由是什么?
-
@crush traumapony自2009年以来一直没有登录。