André Alves de Lima

Talking about Software Development and more…

Você conhece o atributo InternalsVisibleTo?

Eu já abordei anteriormente aqui no blog o funcionamento da classe PrivateObject, que serve para conseguirmos acessar informações privadas de uma classe nos nossos projetos de Unit Tests. Com essa classe nós também conseguimos acessar elementos que tenham o modificador de visibilidade internal. Porém, caso sua necessidade seja somente acessar elementos internal, existe uma maneira muito mais fácil: o atributo InternalsVisibleTo. E é sobre isso que vamos falar no artigo de hoje.

Com o atributo InternalsVisibleTo você consegue marcar um assembly a fim de que todos os elementos com escopo internal nesse assembly estejam disponíveis em um outro assembly. Isso é útil em alguns cenários, principalmente quando queremos acessar algo internal no nosso projeto de Unit Tests.

Para entendermos exatamente como esse atributo funciona e como utilizá-lo, vamos construir um exemplo muito simples.

Primeiramente, crie um projeto do tipo Class Library chamado LibraryASerTestada. Nesse projeto, renomeie a Class1 que é criada automaticamente pelo Visual Studio, de forma que ela tenha o nome de ClasseASerTestada. Nessa classe, vamos criar dois métodos, sendo que um deles terá o escopo public e outro terá o escopo internal:

    public class ClasseASerTestada
    {
        public bool MetodoPublicoQueRetornaTrue()
        {
            return true;
        }
        internal bool MetodoInternalQueRetornaFalse()
        {
            return false;
        }
    }

Feito isso, adicione um novo projeto de Unit Tests à solução chamado ProjetoDeUnitTests. Renomeie UnitTest1 para ClasseASerTestadaTests e TestMethod1 para ClasseASerTestadaTest. Nesse projeto de Unit Tests, adicione uma referência à Class Library que criamos anteriormente:

Agora vamos voltar ao TestMethod e criar os nossos Asserts que checarão o resultado da chamada dos métodos da ClasseASerTestada. Porém, repare que o método chamado MetodoInternalQueRetornaFalse não está visível no nosso projeto de Unit Tests. Isso faz total sentido, uma vez que ele está configurado como internal, o que faz com que ele esteja visível somente dentro do projeto LibraryASerTestada.

É aí que o atributo InternalsVisibleTo entra em ação. Vá até o projeto LibraryASerTestada e abra o arquivo AssemblyInfo.cs:

Adicione a seguinte linha neste arquivo:

[assembly: InternalsVisibleTo("ProjetoDeUnitTests")]

Essa linha utiliza o atributo InternalsVisibleTo para indicar que os elementos internal desse assembly devem ser expostos ao assembly ProjetoDeUnitTests, que é justamente o nosso projeto de Unit Tests, como o próprio nome já diz. Portanto, após adicionar esse atributo, uma vez que voltamos no nosso TestMethod, podemos ver que agora o MetodoInternalQueRetornaFalse está visível:

Dessa forma podemos utilizá-lo normalmente dentro do TestMethod:

    [TestClass]
    public class ClasseASerTestadaTests
    {
        [TestMethod]
        public void ClasseASerTestadaTest()
        {
            LibraryASerTestada.ClasseASerTestada instancia = new LibraryASerTestada.ClasseASerTestada();

            Assert.IsTrue(instancia.MetodoPublicoQueRetornaTrue());
            Assert.IsFalse(instancia.MetodoInternalQueRetornaFalse());
        }
    }

É isso aí. Espero que vocês tenham gostado desse truque. O código deste exemplo está disponível no meu GitHub.

Até o próximo artigo!

André Lima

[Photo credit: www.LendingMemo.com]

Deixe uma resposta

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *