Testar acionadores do Apex
Objetivos de aprendizagem
Após concluir esta unidade, você estará apto a:
- Escrever um teste para um acionador que dispara em uma operação de registro simples.
- Executar todos os métodos de teste de uma classe.
Pré-requisitos
Vamos testar um acionador com o qual trabalhamos no módulo Acionadores do Apex. Se um registro de conta tiver oportunidades relacionadas, o acionador AccountDeletion impede a exclusão do registro.
Se você ainda não tiver adicionado o acionador AccountDeletion, siga os passos abaixo.
- Em Web Console (Console da Web), pressione Ctrl+Shift+P (Windows) ou ⌘+Shift+P (macOS) para abrir a paleta de comandos.
- Insira
SFDX: Create Apex Triggere pressione Enter.
- Como nome do projeto, insira
AccountDeletione pressione Enter.
- Para o sObject, selecione Account (Conta) e pressione Enter.
- Para o evento do acionador, selecione before delete e pressione Enter.
- Para o diretório de saída, selecione force-app/main/default/triggers e pressione Enter.
- Substitua o corpo padrão do acionador por este exemplo.
trigger AccountDeletion on Account (before delete) {
// Prevent the deletion of accounts if they have related opportunities.
for(Account a : [SELECT Id FROM Account
WHERE Id IN (SELECT AccountId FROM Opportunity) AND
Id IN :Trigger.old WITH USER_MODE]) {
Trigger.oldMap.get(a.Id).addError('Cannot delete account with related opportunities.');
}
}Se você tiver adicionado o acionador AccountDeletion em uma unidade anterior, mas depois o tiver desativado para que o sistema pudesse verificar seu desafio, reative-o.
- Em Setup (Configuração), pesquise
Apex Triggers(Acionadores do Apex).
- Na página Apex Triggers (Acionadores do Apex), clique em Edit (Editar), próximo ao acionador
AccountDeletion.
- Selecione Is Active (Está ativo).
- Clique em Save (Salvar).
Se sua organização contiver acionadores de uma unidade anterior, chamados AddRelatedRecord, CalloutTrigger ou HelloWorldTrigger, desative-os. Por exemplo, para desativar o acionador AddRelatedRecord:
- Em Setup (Configuração), pesquise
Apex Triggers(Acionadores do Apex).
- Na página Apex Triggers (Acionadores do Apex), clique em Edit (Editar) ao lado do acionador
AddRelatedRecord.
- Desmarque a opção Is Active (Está ativo).
- Clique em Save (Salvar).
Para desativar os acionadores HelloWorldTrigger e CalloutTrigger, repita os passos acima.
Adicionar e executar um teste de unidade
Antes de implantar um acionador, escreva testes de unidade que executem ações que disparam o acionador e verifique os resultados previstos.
Primeiramente, vamos começar adicionando um método de teste. Este método de teste verifica o que o acionador foi projetado para fazer (o caso positivo): impedir que uma conta seja excluída se ela possuir oportunidades relacionadas.
- Em Web Console (Console da Web), pressione Ctrl+Shift+P (Windows) ou ⌘+Shift+P (macOS) para abrir a paleta de comandos.
- Insira
SFDX: Create Apex Classe pressione Enter.
- Para o tipo de modelo, selecione DefaultApexClass e pressione Enter.
- Como nome da classe, insira
TestAccountDeletione pressione Enter.
- Para o diretório de saída, selecione force-app/main/default/classes e pressione Enter.
- Substitua o corpo de classe padrão pelo seguinte.
@IsTest
private with sharing class TestAccountDeletion {
@IsTest
static void TestDeleteAccountWithOneOpportunity() {
// Test data setup
// Create an account with an opportunity, and then try to delete it
Account acct = new Account(Name='Test Account');
insert as user acct;
Opportunity opp = new Opportunity(
Name=acct.Name + ' Opportunity',
StageName='Prospecting',
CloseDate=System.today().addMonths(1),
AccountId=acct.Id);
insert as user opp;
// Perform test
Test.startTest();
Database.DeleteResult result = Database.delete(acct, false, AccessLevel.USER_MODE);
Test.stopTest();
// Verify
// In this case the deletion should have been stopped by the trigger,
// so verify that we got back an error.
Assert.isFalse(result.isSuccess());
Assert.isTrue(result.getErrors().size() > 0);
Assert.areEqual('Cannot delete account with related opportunities.',
result.getErrors()[0].getMessage());
}
}O método de teste primeiro configura uma conta de teste com uma oportunidade. Em seguida, ele exclui a conta de teste, o que dispara o acionador AccountDeletion. O método de teste verifica se o acionador impediu a exclusão da conta de teste por meio da verificação do valor de retorno da chamada Database.delete(). O valor de retorno é um objeto Database.DeleteResult que contém informações sobre a operação de exclusão. O método de teste verifica se a exclusão não foi efetuada e também a mensagem de erro obtida.
- Salve a classe de teste.
- No Web Console, clique em
na barra de atividades. O painel lateral Testing (Testes) é aberto.
- Na barra de pesquisa Testing (Testes), insira
TestAccountDeletion.
- Para executar todos os métodos de teste na classe, passe o cursor sobre a linha TestAccountDeletion e clique em
.
A classe de teste TestAccountDeletion contém apenas um método de teste, que testa um único registro de conta. Além disso, esse teste é para o caso positivo. Teste sempre mais cenários para se certificar de que o acionador funciona em todos os casos, incluindo a exclusão de uma conta sem oportunidades e exclusões de conta em massa.
Os dados de teste são configurados dentro do método de teste, o que pode se tornar demorado, à medida que você adiciona mais métodos de teste. Se você tiver muitos métodos de teste, ponha a criação de dados de teste em uma classe de utilitário de teste e chame a classe de utilitário a partir de múltiplos métodos de teste. A próxima unidade mostra como tirar vantagem de uma classe de utilitário de teste e adicionar mais métodos de teste.
Quero saber mais
O método de teste contém o par de métodos Test.startTest() e Test.stopTest(), que delimita um bloco de código para obter um conjunto novo de limites do administrador. Neste teste, a configuração de dados de teste usa duas instruções DML antes da execução do teste. Para testar se o código do Apex é executado dentro dos limites de administrador, isole a utilização do limite de configuração de dados daquela de seu teste. Para isolar a utilização do limite do processo de configuração de dados, coloque a chamada de teste dentro do bloco Test.startTest() e Test.stopTest(). Use esse bloco de teste também ao testar o Apex assíncrono. Para obter mais informações, consulte Usando limites, startTest e stopTest.
Recursos
- Guia do desenvolvedor do Apex: Compreender testes no Apex
- Guia do desenvolvedor do Apex: Acionadores
Preparar-se para o desafio prático
Para completar o desafio prático desta unidade, você precisará criar um novo acionador do Apex no objeto Contato chamado RestrictContactByName com o código abaixo:
trigger RestrictContactByName on Contact (before insert, before update) {
//check contacts prior to insert or update for invalid data
for(Contact c : Trigger.New) {
if(c.LastName == 'INVALIDNAME') {
//invalidname is invalid
c.AddError('The Last Name "'+c.LastName+'" is not allowed for DML');
}
}
}