No artigo anterior eu mostrei o uso da classe TelemetryClient para catalogar informações customizadas. O fato de utilizar a classe em sua configuração padrão, fará com que as informações sejam enviadas para o serviço (na nuvem) mesmo que você ainda esteja em ambiente de testes. Talvez isso não seja o que estamos querendo, pois espalhamos pelo código os pontos que são cruciais para enviar as informações, mas talvez só faça sentido quando estive em ambiente de produção.
A classe TelemetryClient confia nas configurações que são disponibilizadas pela classe TelemetryConfiguration. Ela, por sua vez, possui uma propriedade estática chamada Active que retorna as configurações globais (para a aplicação) do Application Insights. A partir daí podemos recorrer a propriedade DisableTelemetry que quando definida como true, não enviará as informações ao serviço. Para utiliza-la podemos também condicionar à diretiva de DEBUG para somente desabilitar enquanto estivermos em desenvolvimento:
#if DEBUG
TelemetryConfiguration.Active.DisableTelemetry = true;
#endif
Ainda com o exemplo utilizado no artigo anterior, não estávamos nos preocupando com os testes unitários. É uma preocupação que também devemos ter para não reportar os eventos quando estamos rodando os testes. Apesar da opção acima resolver, as vezes podemos querer validar se o nosso código está ou não reportando quando necessário e se as informações que foram levadas estão de acordo com a nossa expectativa.
A classe de configuração também nos permite configurar o canal de comunicação, e com isso customizar (sobrescrever) onde e como queremos armazenar os logs. Só que antes de visualizarmos o código necessário para alcançar isso, vamos entender a dependência entre a classe TelemetryClient e o restante da configuração.
A classe TelemetryClient possui dois overloads, onde um deles espera a instância da classe TelemetryConfiguration, que se for omitida, o Application Insights utiliza o valor fornecido pela propriedade Active. A classe TelemetryConfiguration possui uma propriedade chamada TelemetryChannel, onde podemos customizar o canal de comunicação através da implementação da interface ITelemetryChannel. Para o exemplo, vou optar por armazenar os logs em uma coleção interna, conforme é possível ver no código abaixo:
public class TestChannel : ITelemetryChannel
{
private readonly IList<ITelemetry> itens;
public TestChannel()
{
this.itens = new List<ITelemetry>();
}
public void Send(ITelemetry item)
{
this.itens.Add(item);
}
public IList<ITelemetry> Itens
{
get
{
return this.itens;
}
}
//outros membros, omitidos por questão de espaço
}
Depois da classe implementada, precisamos criar a instância e associa-la à propriedade da configuração para que ela passe a ser utilizada quando chamarmos os métodos para catalogar as informações (Track*). O código que foi criado para calcular o frete não foi alterado em nada. Mesmo que a configuração tenha sido realizada externamente, a classe TelemetryClient irá utilizar esta classe via TelemetryConfiguration (via propriedade Active). O teste ficaria da seguinte forma:
[TestClass]
public class CalculadoraDeFrete
{
private TestChannel channel;
[TestInitialize]
public void Inicializar()
{
this.channel = new TestChannel();
TelemetryConfiguration.Active.TelemetryChannel = channel;
}
[TestMethod]
public void DeveCalcularFreteParaValinhos()
{
var cep = “13273-047”;
var valorEsperado = 12.38M;
var calculadora = new CalculadoraDeFrete();
var resultado = calculadora.Calcular(cep);
Assert.AreEqual(valorEsperado, resultado);
var evento = this.channel.Itens.Single() as EventTelemetry;
Assert.AreEqual(“CalculoDeFrete”, evento.Name);
Assert.AreEqual(cep, evento.Properties[“Cep”]);
Assert.AreEqual(resultado.ToString(), evento.Properties[“Resultado”]);
}
}