C# 使代码在内部但可用于其他项目的单元测试
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/106907/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Making code internal but available for unit testing from other projects
提问by leora
We put all of our unit tests in their own projects. We find that we have to make certain classes public instead of internal just for the unit tests. Is there anyway to avoid having to do this. What are the memory implication by making classes public instead of sealed?
我们将所有的单元测试放在他们自己的项目中。我们发现我们必须为单元测试公开某些类而不是内部类。有没有办法避免这样做。将类公开而不是密封对内存有什么影响?
采纳答案by Ash
If you're using .NET, the InternalsVisibleToassembly attribute allows you to create "friend" assemblies. These are specific strongly named assemblies that are allowed to access internal classes and members of the other assembly.
如果您使用 .NET,InternalsVisibleTo程序集属性允许您创建“朋友”程序集。这些是特定的强命名程序集,允许访问其他程序集的内部类和成员。
Note, this should be used with discretion as it tightly couples the involved assemblies. A common use for InternalsVisibleTo is for unit testing projects. It's probably not a good choice for use in your actual application assemblies, for the reason stated above.
请注意,这应该谨慎使用,因为它紧密耦合了所涉及的程序集。InternalsVisibleTo 的一个常见用途是用于单元测试项目。由于上述原因,在实际应用程序程序集中使用它可能不是一个好的选择。
Example:
例子:
[assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{
回答by TraumaPony
Classes can be both public AND sealed.
类既可以是公开的,也可以是密封的。
But, don't do that.
但是,不要那样做。
You can create a tool to reflect over internal classes, and emit a new class that accesses everything via reflection. MSTest does that.
您可以创建一个工具来反射内部类,并发出一个通过反射访问所有内容的新类。MSTest 就是这样做的。
Edit: I mean, if you don't want to include -any- testing stuff in your original assembly; this also works if the members are private.
编辑:我的意思是,如果您不想在原始程序集中包含任何测试内容;如果成员是私人的,这也有效。
回答by Josh
If it is an internal class then it must not be getting used in isolation. Therefore you shouldn't really be testing it apart from testing some other class that makes use of that object internally.
如果它是一个内部类,那么它不能被孤立使用。因此,除了测试在内部使用该对象的其他类之外,您不应该真正测试它。
Just as you shouldn't test private members of a class, you shouldn't be testing internal classes of a DLL. Those classes are implementation details of some publicly accessible class, and therefore should be well exercised through other unit tests.
正如您不应该测试类的私有成员一样,您也不应该测试 DLL 的内部类。这些类是一些可公开访问的类的实现细节,因此应该通过其他单元测试很好地练习。
The idea is that you only want to test the behavior of a class because if you test internal implementation details then your tests will be brittle. You should be able to change the implementation details of any class without breaking all your tests.
这个想法是你只想测试一个类的行为,因为如果你测试内部实现细节,那么你的测试就会很脆弱。您应该能够在不破坏所有测试的情况下更改任何类的实现细节。
If you find that you really need to test that class, then you might want to reexamine why that class is internal in the first place.
如果您发现确实需要测试该类,那么您可能首先要重新检查为什么该类是内部类。
回答by ktutnik
for documentation purposes
用于文档目的
alternatively you can instantiate internal class by using Type.GetType
method
或者,您可以使用Type.GetType
方法实例化内部类
example
例子
//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*/ });
for generic type there are different process as bellow:
对于泛型类型,有如下不同的过程:
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*/});