Fazendo código interno, mas está disponível para teste de unidade de outros projectos

StackOverflow https://stackoverflow.com/questions/106907

  •  01-07-2019
  •  | 
  •  

Pergunta

Nós colocamos todos os nossos testes de unidade em seus próprios projetos. Nós achamos que temos que fazer certas classes público em vez de interna apenas para os testes de unidade. Existe uma maneira de evitar ter que fazer isso. Quais são as implicações de memória, fazendo aulas público em vez de selada?

Foi útil?

Solução

Se você estiver usando .NET, o InternalsVisibleTo montagem atributo permite criar montagens de "amigo". Estes são específicas montagens fortemente nomeados que estão autorizados a classes e membros do outro conjunto interno de acesso.

Note, este deve ser usado com critério, se firmemente casais Os conjuntos envolvidos. Um uso comum para InternalsVisibleTo é para projectos de teste de unidade. Provavelmente não é uma boa escolha para uso em seus conjuntos de aplicações reais, pela razão indicada acima.

Exemplo:

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

Outras dicas

Se é uma classe interna, então ele não deve estar sendo usado isoladamente. Portanto, você não deve realmente ser testá-lo para além de testar alguma outra classe que faz uso desse objeto internamente.

Assim como você não deve testar os membros privados de uma classe, você não deve estar testando as classes internas de uma DLL. Essas classes são detalhes de implementação de alguma classe de acesso público e, portanto, deve ser bem exercida através de outros testes de unidade.

A idéia é que você só quer testar o comportamento de uma classe porque se você testar detalhes de implementação interna, em seguida, seus testes será frágil. Você deve ser capaz de mudar os detalhes de implementação de qualquer classe sem quebrar todos os seus testes.

Se você achar que você realmente precisa de teste que classe, então você pode querer reexaminar por que essa classe é interno em primeiro lugar.

para fins de documentação

Como alternativa, você pode instanciar a classe interna usando o método Type.GetType

exemplo

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

para o tipo genérico há processo diferente como abaixo:

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

As aulas podem ser tanto pública e selado.

Mas, não faça isso.

Você pode criar uma ferramenta para refletir sobre classes internas, e emitem uma nova classe que acessa tudo através da reflexão. MSTest faz isso.

Edit: Eu quero dizer, se você não quiser incluir -qualquer- testar coisas em sua montagem original; isso também funciona se os membros são privados.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top