[C#] 내부적으로 코드를 작성하지만 다른 프로젝트에서 단위 테스트에 사용 가능

우리는 모든 단위 테스트를 자체 프로젝트에 넣었습니다. 우리는 단위 테스트를 위해 내부 대신 특정 클래스를 공개해야한다는 것을 알았습니다. 어쨌든 이것을 피할 수 있습니까? 봉인 대신 클래스를 공개함으로써 메모리에 미치는 영향은 무엇입니까?



답변

.NET을 사용하는 경우 InternalsVisibleTo 어셈블리 속성을 사용하면 “친구”어셈블리를 만들 수 있습니다. 이들은 내부 클래스와 다른 어셈블리의 멤버에 액세스 할 수있는 강력한 이름의 어셈블리입니다.

이것은 관련된 어셈블리를 단단히 결합하므로 신중하게 사용해야합니다. InternalsVisibleTo의 일반적인 용도는 단위 테스트 프로젝트입니다. 위에서 언급 한 이유로 실제 응용 프로그램 어셈블리에 사용하기에 적합하지 않을 수 있습니다.

예:

[assembly: InternalsVisibleTo("NameAssemblyYouWantToPermitAccess")]
namespace NameOfYourNameSpace
{


답변

내부 클래스 인 경우 격리 된 상태로 사용해서는 안됩니다. 따라서 내부적으로 해당 객체를 사용하는 다른 클래스를 테스트하는 것과 별도로 테스트해서는 안됩니다.

클래스의 개인 멤버를 테스트하지 않아야하는 것처럼 DLL의 내부 클래스를 테스트해서는 안됩니다. 이러한 클래스는 공개적으로 액세스 가능한 클래스의 구현 세부 사항이므로 다른 단위 테스트를 통해 잘 연습해야합니다.

내부 구현 세부 사항을 테스트하면 테스트가 취약하기 때문에 클래스의 동작 만 테스트하려는 것이 좋습니다. 모든 테스트를 중단하지 않고 모든 클래스의 구현 세부 사항을 변경할 수 있어야합니다.

해당 클래스를 실제로 테스트해야하는 경우, 해당 클래스가 왜 내부에 있는지 이유를 다시 검토 할 수 있습니다.


답변

문서화 목적으로

또는 Type.GetType메소드 를 사용하여 내부 클래스를 인스턴스화 할 수 있습니다

//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*/ });

제네릭 형식의 경우 다음과 같은 다른 프로세스가 있습니다.

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는 그렇게합니다.

편집 : 원래 어셈블리에 테스트 항목을 포함하지 않으려는 경우; 멤버가 비공개 인 경우에도 작동합니다.


답변