Versões comparadas

Chave

  • Esta linha foi adicionada.
  • Esta linha foi removida.
  • A formatação mudou.

...

Painel
titleTestando a Funcionalidade Assíncrona

Ao implementar o padrão MVVM, os ViewModels geralmente invocam operações em serviços de forma assíncrona. Os testes de código que invocam essas operações normalmente usam simulações como substitutos dos serviços reais. O exemplo de código a seguir demonstra o teste da funcionalidade assíncrona passando um serviço fictício para um modelo de exibição:

Bloco de código
languagec#
themeRDark
titleC#
[Fact]
public async Task GetFakeUserLoginModelTest()
{
  string login = "mestre";

  var userLoginService = new MockUserLoginService();
  var model = await userLoginService.GetAsync(login);

  Assert.Equal(login, model.login);
}

Clique para acessar o arquivo

Este teste de unidade unitário verifica se apropriedade login dainstância UserLoginService terá o mesmo valor criado no inicio do teste depois que ométodo GetAsync for invocado. 

Painel
titleTestando Implementações de INotifyPropertyChanged

A implementação dainterface INotifyPropertyChanged permite que as Views reajam às alterações originadas de Models e ViewModels. Essas alterações não estão limitadas aos dados mostrados nos controles -- elas também são usadas para controlar a View, como os estados do ViewModel que fazem com que as animações sejam iniciadas ou os controles sejam desabilitados.

As propriedades que podem ser atualizadas diretamente pelo teste unitário podem ser testadas anexando um manipulador de eventos aoevento PropertyChanged e verificando se o evento é gerado após definir um novo valor para a propriedade. O exemplo de código a seguir mostra esse teste:

Bloco de código
languagec#
themeRDark
titleC#
[Fact]
public void SettingMensagemErroLoginPropertyShouldRaisePropertyChanged()
{
  var invoked = false;
  var loginViewModel = new LoginViewModel(_webApiService, _configService, _userLoginService, _navigationService);

  loginViewModel.PropertyChanged += (_, e) =>
  {
    if (e?.PropertyName?.Equals(nameof(LoginViewModel.MensagemErroLogin)) ?? false)
    {
      invoked = true;
    }
  };

  loginViewModel.IsMock = true;
  loginViewModel.Login.Value = "error";
  loginViewModel.Senha.Value = "error";
  loginViewModel.LoginCommand.Execute(null);

  Assert.True(invoked);
}

Clique para acessar o arquivo

Este teste de unidade unitário invoca ocomando LoginCommand daclasse LoginViewModel, que faz com que suapropriedade MensagemErroLogin seja atualizada. O teste será aprovado, desde que oevento PropertyChanged seja gerado para apropriedade MensagemErroLogin.

Painel
titleTestando a Comunicação Baseada em Mensagens

Os ViewModels que usam aclasse MessagingCenter para se comunicar entre classes fracamente acopladas podem ser testados na unidade, assinando a mensagem enviada pelo código em teste, conforme demonstrado no exemplo de código a seguir:

Bloco de código
languagec#
themeRDark
titleC#
[Fact]
public void ShowPassCommandSendsLoginShowPassMessageTest()
{
  var messageReceived = false;
  var loginViewModel = new LoginViewModel(_webApiService, _configService, _userLoginService, _navigationService);

  MessagingCenter.Subscribe<RMSLoginViewModel>(this, MessageKeys.LoginShowPass, (sender) =>
  {
    messageReceived = true;
  });

  loginViewModel.ShowPassCommand.Execute(null);

  Assert.True(messageReceived);
}

Clique para acessar o arquivo

Este teste de unidade unitário verifica se o LoginViewModel publica amensagem LoginShowPass em resposta à suaexecução do comando ShowPassCommand. Como aclasse MessagingCenter oferece suporte a assinaturas de mensagem multicast, o teste de unidade pode assinar amensagem LoginShowPass e executar uma rotina de callback em resposta ao recebimento dela. Essa rotina de callback, especificada como uma expressão lambda, define um campo booleano usado pelainstrução Assert para verificar o comportamento do teste.

Painel
titleTestando Tratamento de Exceção

Testes de unidade também podem ser escritos para verificar se exceções específicas são lançadas para ações ou entradas inválidas, conforme demonstrado no exemplo de código a seguir:

Bloco de código
languagec#
themeRDark
titleC#
[Fact]
public void InvalidLoginShouldThrowException()
{
  string login = string.Empty;

  var userLoginService = new MockUserLoginService();

  Assert.ThrowsAsync<Exception>(async () => await userLoginService.GetAsync(login));
}

Clique para acessar o arquivo

Este teste de unidade unitário lançará uma exceção porque o objeto MockUserLoginService espera um parâmetro diferente de nulo e vazio. Ométodo Assert.Throws<T> é um método genérico onde T é o tipo da exceção esperada. O argumento passado para ométodo Assert.Throws<T> é uma expressão lambda que lançará a exceção. Portanto, o teste de unidade será aprovado, desde que a expressão lambda lance umException.

Dica
titleDica

Evite escrever testes de unidade que examinam comparem strings de mensagens de exceção. As cadeias de caracteres de mensagens de exceção podem mudar com o tempo e, portanto, os testes de unidade que dependem de sua presença dessa comparação são considerados frágeis.