Um projeto de teste de unidade pode carregar o arquivo app.config do aplicativo de destino?

150

Estou testando por unidade um aplicativo .NET (.exe) que usa um arquivo app.config para carregar propriedades de configuração. O aplicativo de teste de unidade em si não possui um arquivo app.config.

Quando tento testar um método que utiliza qualquer uma das propriedades de configuração, eles retornam nulos . Estou assumindo que isso ocorre porque o aplicativo de teste de unidade não será carregado no app.config do aplicativo de destino.

Existe uma maneira de substituir isso ou eu tenho que escrever um script para copiar o conteúdo do app.config de destino em um app.config local?

Esse post meio que faz essa pergunta, mas o autor está realmente olhando para ela de um ângulo diferente do que eu.

EDIT: devo mencionar que estou usando o VS08 Team System para meus testes de unidade.

Jordan Parmer
fonte

Respostas:

59

A maneira mais simples de fazer isso é adicionar o .configarquivo na seção de implantação no seu teste de unidade.

Para fazer isso, abra o .testrunconfigarquivo nos Itens da solução. Na seção Implantação, adicione os .configarquivos de saída do diretório de construção do seu projeto (presumivelmente bin\Debug).

Qualquer coisa listada na seção de implantação será copiada para a pasta de trabalho do projeto de teste antes da execução dos testes, para que seu código dependente da configuração funcione corretamente.

Editar: esqueci de adicionar, isso não funcionará em todas as situações; portanto, você pode precisar incluir um script de inicialização que renomeie a saída .configpara corresponder ao nome do teste de unidade.

Jeromy Irvine
fonte
9
É muito mais fácil adicionar um app.config fiel ao projeto de teste - você não precisa brincar com o .testrunconfig.
Rowland Shaw
13
@ Rowland, se você fizer isso, precisará manter duas cópias do app.config. Prefiro gastar 10 segundos, uma vez, usando a ferramenta .testrunconfig do que ter que lembrar de atualizar o app.config nos dois lugares.
Jeromy Irvine
66
Você não pode simplesmente adicionar uma referência de não cópia? (Add Item Existent ...)
EFraim
6
O comentário de EFraim deve ser a resposta aceita, isso é muito mais simples do que qualquer outra coisa.
Reggaeguitar
28
Para o soln do EFraim: Certifique-se de usar o "Adicionar como link" no botão de comando. Caso contrário, você ainda receberá uma cópia. Além disso, embora a pergunta seja especificamente para um aplicativo .Net, isso não funcionará para um aplicativo Web, pois a configuração de um aplicativo Web tem o nome errado (Web.Config, não App.Config)
Rob Von Nesselrode
103

No Visual Studio 2008, adicionei o app.configarquivo ao projeto de teste como um item existente e selecionei a cópia como link para garantir que não seja duplicado. Dessa forma, só tenho uma cópia na minha solução. Com vários projetos de teste, é realmente útil!

Adicionar item existente

Adicionar como link

bbodenmiller
fonte
7
Resposta perfeita, simples e objetiva! +1
Custodio
2
Esta é a melhor solução e deve ser marcada como a resposta.
Niaher
4
Para adicionar um item existente "como um link", você deve: "Na caixa de diálogo Adicionar Item Existente, localize e selecione o item do projeto que deseja vincular" e: "Na lista suspensa do botão Abrir, selecione Adicionar como Link. "
2213 uriel
Isso funcionou muito bem para mim. Estou tentando pensar em uma situação em que não daria certo ... e já pensei o suficiente agora. Obrigado!
precisa saber é o seguinte
53

Esteja você usando o Team System Test ou o NUnit , a melhor prática é criar uma biblioteca de classes separada para seus testes. Simplesmente adicionar um App.config ao seu projeto de Teste será automaticamente copiado para sua pasta bin quando você compilar .

Se o seu código depende de testes de configuração específicos, o primeiro teste que eu escreveria valida a disponibilidade do arquivo de configuração ( para que eu saiba que não sou louco ):

<configuration>
   <appSettings>
       <add key="TestValue" value="true" />
   </appSettings>
</configuration>

E o teste:

[TestFixture]
public class GeneralFixture
{
     [Test]
     public void VerifyAppDomainHasConfigurationSettings()
     {
          string value = ConfigurationManager.AppSettings["TestValue"];
          Assert.IsFalse(String.IsNullOrEmpty(value), "No App.Config found.");
     }
}

Idealmente, você deve escrever um código para que seus objetos de configuração sejam passados ​​para suas classes. Isso não apenas o separa do problema do arquivo de configuração, mas também permite que você escreva testes para diferentes cenários de configuração.

public class MyObject
{
     public void Configure(MyConfigurationObject config)
     {
          _enabled = config.Enabled;
     }

     public string Foo()
     {
         if (_enabled)
         {
             return "foo!";
         }
         return String.Empty;
     }

     private bool _enabled;
}

[TestFixture]
public class MyObjectTestFixture
{
     [Test]
     public void CanInitializeWithProperConfig()
     {
         MyConfigurationObject config = new MyConfigurationObject();
         config.Enabled = true;

         MyObject myObj = new MyObject();
         myObj.Configure(config);

         Assert.AreEqual("foo!", myObj.Foo());
     }
}
bryanbcook
fonte
2
Eu concordo com o espírito de passar na dependência de configuração aqui, isso parece ter sido respondido, por Mark Seemann, não menos! aqui: Falhando testes de unidade devido à falta de arquivo.config
Shaun
Há um "ausente da linha: valor da string = ConfigurationManager.AppSettings [" TestValue]; Tentei corrigi-lo, mas teria que encontrar mais 5 caracteres para corrigir para obter o stackoverflow para permitir uma edição.
21412 Jane
22

Se você possui uma solução que contém, por exemplo, Aplicativo da Web e Projeto de Teste, provavelmente deseja que o Projeto de Teste use o web.config do Aplicativo da Web.

Uma maneira de resolver isso é copiar o web.config para testar o projeto e renomeá-lo como app.config.

Outra e melhor solução é modificar a cadeia de construção e fazer uma cópia automática do web.config para testar o diretório de saída dos projetos. Para fazer isso, clique com o botão direito do mouse em Aplicativo de Teste e selecione Propriedades. Agora você deve ver as propriedades do projeto. Clique em "Build Events" e, em seguida, clique em "Edit Post-build ...". Escreva a seguinte linha para lá:

copy "$(SolutionDir)\WebApplication1\web.config" "$(ProjectDir)$(OutDir)$(TargetFileName).config"

E clique em OK. (Observe que você provavelmente precisará alterar o WebApplication1 ao projetar o nome que deseja testar). Se você tiver um caminho errado para o web.config, a cópia falhará e você o notará durante a compilação sem êxito.

Editar:

Para copiar do projeto atual para o projeto de teste:

copy "$(ProjectDir)bin\WebProject.dll.config" "$(SolutionDir)WebProject.Tests\bin\Debug\App.Config"
Antti
fonte
Solução muito boa. Isso me ajudou a evitar copiar e duplicar .configarquivos. Obrigado por compartilhar! :)
Leniel Maccaferri
Solução muito boa! Muito obrigado.
Vin Shahrdar
Solução agradável, mas o que acontece quando os principais web.configtêm apenas referências a .configarquivos externos dentro do mesmo projeto. Como o caminho pode apontar apenas para pastas no mesmo diretório (o que é verdadeiro normalmente), ao executar testes, ele não poderá manipular esses arquivos externos. Alguma idéia de como resolvê-lo?
Sugafree
Isso funcionou para mim: copie "$ (SolutionDir) \ MainProject \ Web.config" "$ (ProjectDir) app.config"
Andrew
8

Isso é um pouco antigo, mas achei uma solução melhor para isso. Eu estava tentando a resposta escolhida aqui, mas parece que .testrunconfig já está obsoleto.

1. Para testes de unidade, embrulhe a configuração é uma interface (IConfig)

para testes de unidade, a configuração realmente não deve fazer parte do seu teste, então crie uma simulação que você possa injetar. Neste exemplo, eu estava usando o Moq.

Mock<IConfig> _configMock;
_configMock.Setup(config => config.ConfigKey).Returns("ConfigValue");
var SUT = new SUT(_configMock.Object);

2. Para teste de integração, adicione dinamicamente a configuração necessária

Configuration config = ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
if(config.AppSettings.Settings[configName] != null)
{
    config.AppSettings.Settings.Remove(configName);
}
config.AppSettings.Settings.Add(configName, configValue);
config.Save(ConfigurationSaveMode.Modified, true);
ConfigurationManager.RefreshSection("appSettings");
MichaelChan
fonte
5

Isto é muito fácil.

  • Clique com o botão direito do mouse no seu projeto de teste
  • Adicionar -> Item existente
  • Você pode ver uma pequena seta ao lado do botão Adicionar
  • Selecione o arquivo de configuração, clique em "Adicionar como link"
Hari Das
fonte
4

Se você estiver usando o NUnit, dê uma olhada nesta postagem . Basicamente, você precisará ter seu app.config no mesmo diretório que o arquivo .nunit.

Cory Foy
fonte
Estou usando o VS08 Team System para meus testes de unidade, mas obrigado pela dica do NUnit!
Jordan Parmer
2

Se o seu aplicativo estiver usando configurações como Asp.net ConnectionString, você precisará adicionar o atributo HostType ao seu método, caso contrário, elas não serão carregadas, mesmo que você tenha um arquivo App.Config.

[TestMethod]
[HostType("ASP.NET")] // will load the ConnectionString from the App.Config file
public void Test() {

}
Zyo
fonte
0

Eu uso o NUnit e no diretório do meu projeto tenho uma cópia do meu App.Config que altero algumas configurações (por exemplo, redireciono para um banco de dados de teste ...). Você precisa tê-lo no mesmo diretório do projeto testado e ficará bem.

Patrick Desjardins
fonte
0

Como não consegui obter nenhuma dessas sugestões para trabalhar com o nUnit 2.5.10, acabei usando a funcionalidade Project -> Edit do nUnit para especificar o arquivo de configuração a ser segmentado (como outros disseram que ele precisa estar na mesma pasta que o. próprio arquivo de unidade). O lado positivo disso é que eu posso dar ao arquivo de configuração um nome Test.config, o que torna muito mais claro o que é e por que)

Jane
fonte
0

Seus testes de unidade são considerados como um ambiente que executa seu código para testá-lo. Assim como qualquer ambiente normal, você tem, ou seja, preparação / produção. Pode ser necessário adicionar um .configarquivo para o seu projeto de teste também. Uma solução alternativa é criar uma biblioteca de classes e convertê-la em Projeto de Teste, adicionando os pacotes NuGet necessários, como NUnit e NUnit Adapter. funciona perfeitamente bem com o Visual Studio Test Runner e o Resharper e você tem seu app.configarquivo no seu projeto de teste. insira a descrição da imagem aqui

insira a descrição da imagem aqui

insira a descrição da imagem aqui

insira a descrição da imagem aqui

E finalmente depurei meu teste e valor de App.config:

insira a descrição da imagem aqui

Ben
fonte