Unidade testando o arquivo app.config com NUnit
-
05-07-2019 - |
Pergunta
Quando vocês estão unidade testar um aplicativo que se baseia em valores de um arquivo app? Como você testar que esses valores são lidos corretamente e como o programa de seus reage a valores incorretos inseridos em um arquivo de configuração?
Seria ridículo ter que modificar o arquivo de configuração para o aplicativo NUnit, mas eu não posso ler nos valores do app.config Quero teste.
Edit: eu acho que deveria esclarecer talvez. Eu não estou preocupado com o ConfigurationManager não conseguir ler os valores, mas eu estou preocupado com o teste como meu programa reage aos valores lidos.
Solução
Eu costumo isolar dependências externas, como a leitura de um arquivo de configuração em sua própria fachada de classe com muito pouca funcionalidade. Em testes eu posso criar uma versão simulada desta classe que implementa e utilização que, em vez do arquivo de configuração real. Você pode criar sua própria maquete de ou usar um framework como o MOQ ou Rhino Mocks para isso.
Dessa forma, você pode facilmente experimentar o seu código com valores de configuração diferentes sem escrever testes complexos que os arquivos de configuração xml primeira gravação. O código que lê a configuração é geralmente tão simples que precisa de muito pouco teste.
Outras dicas
Você pode modificar sua seção de configuração em tempo de execução em sua configuração de teste. Por exemplo:
// setup
System.Configuration.Configuration config =
ConfigurationManager.OpenExeConfiguration(ConfigurationUserLevel.None);
config.Sections.Add("sectionname", new ConfigSectionType());
ConfigSectionType section = (ConfigSectionType)config.GetSection("sectionname");
section.SomeProperty = "value_you_want_to_test_with";
config.Save(ConfigurationSaveMode.Modified);
ConfigurationManager.RefreshSection("sectionname");
// carry out test ...
Você pode de configuração claro seus próprios métodos auxiliares para fazer isso de forma mais elegante.
Você pode chamar o método conjunto de ConfigurationManager.AppSettings para definir os valores necessários para esse teste de unidade particular.
[SetUp]
public void SetUp()
{
ConfigurationManager.AppSettings.Set("SettingKey" , "SettingValue");
// rest of unit test code follows
}
Quando o teste de unidade executa-lo, então, usar esses valores para executar o código
Você pode ler e escrever para o arquivo app.config
com a classe ConfigurationManager
Eu estava enfrentando problemas semelhantes com web.config .... I encontrar uma solução interessante. Você pode encapsular função de leitura de configuração, por exemplo, algo como isto:
public class MyClass {
public static Func<string, string>
GetConfigValue = s => ConfigurationManager.AppSettings[s];
//...
}
E, em seguida, normalmente usa
string connectionString = MyClass.GetConfigValue("myConfigValue");
mas na unidade de teste inicializar "substituir" a função como esta:
MyClass.GetConfigValue = s => s == "myConfigValue" ? "Hi", "string.Empty";
Mais sobre isso:
http: // rogeralsing. COM / 2009/05/07 / the-simples-form-de-configurável-dependência de injecção /
A solução mais elegante é usar injeção de dependência velho liso nas definições de configuração próprios. IMHO este é mais limpo do que ter para zombar uma classe de leitura de configuração / embalagem etc.
Por exemplo, digamos que uma classe "Tempo" requer um "ServiceURL", a fim de função (por exemplo, dizem que chama um serviço da web para obter o tempo). Ao invés de ter alguma linha de código que vai ativamente para um arquivo de configuração para obter essa configuração (se que o código seja na classe do tempo ou um leitor de configuração separada que poderia ser ridicularizado como por algumas das outras respostas), a classe tempo pode permitir a configuração para ser injectado, quer através de um parâmetro para o construtor, ou, eventualmente, através de uma propriedade intelectual. Dessa forma, os testes de unidade são extremamente simples e direta, e nem sequer exigem zombando.
O valor da configuração pode então ser injetado usando uma inversão de controle (ou Dependency Injection) recipiente, de modo que os consumidores da classe Tempo não é necessário fornecer explicitamente o valor de algum lugar, como é manipulada pelo contêiner.
Isso funcionou para mim:
public static void BasicSetup()
{
ConnectionStringSettings connectionStringSettings =
new ConnectionStringSettings();
connectionStringSettings.Name = "testmasterconnection";
connectionStringSettings.ConnectionString =
"server=localhost;user=some;database=some;port=3306;";
ConfigurationManager.ConnectionStrings.Clear();
ConfigurationManager.ConnectionStrings.Add(connectionStringSettings);
}
Você pode sempre envolver a leitura-in pouco em uma interface, e tem uma implementação específica ler a partir do arquivo de configuração. Você, então, escrever testes utilizando Mock Objects para ver como o programa tratada valores ruins. Pessoalmente, eu não iria testar esta aplicação específica, como este é o código .NET Framework (e eu estou supondo que - espero - a MS já testei).
System.Configuration.Abstractions é uma coisa de beleza quando se trata de testar este tipo de coisas.
Aqui está o site do projeto GitHub com alguns bons exemplos: indique descrição link aqui
Aqui está o site do NuGet: https://www.nuget.org/packages /System.Configuration.Abstractions/
Eu uso isso em quase todos os meus projetos .NET.
Na verdade, o pensamento sobre ele ainda, acho que eu deveria fazer é criar uma classe ConfigFileReader para uso em meu projeto e, em seguida, fingir no equipamento de teste de unidade?
É que a coisa habitual fazer?
A opção mais simples é envolver os métodos que ler a configuração de tal forma que você pode substituir em valores durante os testes. Criar uma interface que você usa para ler config e ter uma implementação dessa interface são passadas como um parâmetro construtor ou conjunto sobre o objeto como uma propriedade (como você faria usando a injeção de dependência / inversão de controle). No ambiente de produção, passar em uma implementação que realmente lê de configuração; no ambiente de teste, passar em uma implementação de teste que retorna um valor conhecido.
Se você não tem a opção de refatoração do código para testability mas ainda preciso testá-lo, Typemock Isolador oferece a capacidade de realmente zombar classes .NET Framework Configuration para que você pode simplesmente dizer "próxima vez que eu pedir para tal -e-tal valor appSettings, devolver este valor conhecido. "
Eu tive o mesmo problema,
Você pode usar Nunit-console.exe c: \ caminho1 \ testdll1.dll c: \ path2 \ testdll2.dll
isso funciona bem, embora se ambos os dlls apontam para diferentes app.configs ex testdll1.dll.config e testdll2.dll.config
Se você quiser usar Nunit configuração do projeto e envolver esses dois DLLs, então não há nenhuma maneira você pode ter duas configurações
Você tem que ter project1.config se seu projeto Nunit é project1.nunit no mesmo local que Project1.nunit senta.
espero que isso ajude
Bem, eu só tive o mesmo problema ... Eu queria testar um projeto BL que é referenciado a partir de um web site. mas eu queria testar apenas o BL. Assim, no caso de pré-construção do projeto de teste que eu copiar os arquivos App.config no bin \ pasta de depuração e referenciá-los a partir do app.config ...