Criar dados de teste para testes do Apex
Objetivos de aprendizagem
Após concluir esta unidade, você estará apto a:
- Criar uma classe de utilitário de teste.
- Usar um método de utilitário de teste para configurar os dados de teste de diversos casos de teste.
- Executar todos os métodos de teste de uma classe.
Criar dados de teste para testes do Apex
Use classes de utilitário de teste para adicionar métodos reutilizáveis para a configuração de dados de teste.
Pré-requisitos
Conclua os pré-requisitos na unidade anterior, Testar acionadores do Apex, se ainda não o fez.
Adicionar uma classe de utilitário de teste
Vamos refatorar o método de teste anterior substituindo a criação de dados de teste por uma chamada a um método de classe de utilitário. Primeiro, você precisa criar a classe de utilitário de teste.
A classe TestDataFactory
é um tipo especial de classe — é uma classe pública anotada com @isTest
e que só pode ser acessada a partir de um teste em execução. Classes de utilitário de teste contêm métodos que podem ser chamados por métodos de teste para executar tarefas úteis, como configurar dados de teste. Classes de utilitário de teste são excluídas do limite de tamanho de código da organização.
Para adicionar a classe TestDataFactory
:
- No Developer Console, clique em File (Arquivo) | New (Novo) | Apex Class (Classe do Apex), digite
TestDataFactory
como o nome da classe e, em seguida, clique em OK. - Substitua o corpo de classe padrão pelo seguinte.
@isTest public class TestDataFactory { public static List<Account> createAccountsWithOpps(Integer numAccts, Integer numOppsPerAcct) { List<Account> accts = new List<Account>(); for(Integer i=0;i<numAccts;i++) { Account a = new Account(Name='TestAccount' + i); accts.add(a); } insert accts; List<Opportunity> opps = new List<Opportunity>(); for(Integer j=0;j<numAccts;j++) { Account acct = accts[j]; // For each account just inserted, add opportunities for(Integer k=0;k<numOppsPerAcct;k++) { opps.add(new Opportunity(Name=acct.Name + ' Opportunity ' + k, StageName='Prospecting', CloseDate=System.today().addMonths(1), AccountId=acct.Id)); } } // Insert all opportunities for all accounts. insert opps; return accts; } }
Essa classe de utilitário de teste contém um método estático, createAccountsWithOpps()
, que aceita o número de contas (contido no parâmetro numAccts
) e o número de oportunidades relacionadas a serem criadas para cada conta (contido no parâmetro numOppsPerAcct
). O primeiro loop no método cria o número específico de contas e as armazena na variável da lista accts
. Após o primeiro loop, a instrução DML insert()
é chamada para criar todas as contas na lista no banco de dados.
O segundo loop cria as oportunidades. Como cada grupo de oportunidades está vinculado a uma conta, o loop externo itera nas diferentes contas e contém um loop aninhado que cria oportunidades relacionadas para a conta atual. Da próxima vez que o loop aninhado for executado, as oportunidades são adicionadas à mesma lista usando o método add()
. As oportunidades são vinculadas a suas contas pai usando o campo AccountId
. O número total de todas as oportunidades que são criadas é o produto do número de oportunidades pelo número de contas (numOppsPerAcct
*numAccts
). Em seguida, a instrução DML insert()
é chamada com eficiência fora do loop para criar todas as oportunidades na coleção para todas as contas em apenas uma chamada.
Finalmente, esse método fornece uma lista das novas contas.
Chamar métodos de utilitário para a criação de dados de teste
Agora que você adicionou a classe de utilitário de teste, modifique a classe de teste TestAccountDeletion
para aproveitar essa classe. A matriz fornecida pela chamada TestDataFactory.createAccountsWithOpps(1,1)
contém um sObject de Conta.
Aqui está o método de teste modificado. Uma versão mais curta!
@isTest private class TestAccountDeletion { @isTest static void TestDeleteAccountWithOneOpportunity() { // Test data setup // Create one account with one opportunity by calling a utility method Account[] accts = TestDataFactory.createAccountsWithOpps(1,1); // Perform test Test.startTest(); Database.DeleteResult result = Database.delete(accts[0], false); Test.stopTest(); // Verify that the deletion should have been stopped by the trigger, // so check that we got back an error. System.assert(!result.isSuccess()); System.assert(result.getErrors().size() > 0); System.assertEquals('Cannot delete account with related opportunities.', result.getErrors()[0].getMessage()); } }
Testar diferentes condições
Um método de teste não é suficiente para testar todas as entradas possíveis para o acionador. É preciso testar algumas outras condições, como quando uma conta sem oportunidades é excluída. É preciso também testar os mesmos cenários com um grande número de registros, em vez de com apenas um registro. Aqui está uma versão atualizada da classe de teste que contém os três métodos de teste adicionais. Salve essa versão atualizada da classe.
@isTest private class TestAccountDeletion { @isTest static void TestDeleteAccountWithOneOpportunity() { // Test data setup // Create one account with one opportunity by calling a utility method Account[] accts = TestDataFactory.createAccountsWithOpps(1,1); // Perform test Test.startTest(); Database.DeleteResult result = Database.delete(accts[0], false); Test.stopTest(); // Verify that the deletion should have been stopped by the trigger, // so check that we got back an error. System.assert(!result.isSuccess()); System.assert(result.getErrors().size() > 0); System.assertEquals('Cannot delete account with related opportunities.', result.getErrors()[0].getMessage()); } @isTest static void TestDeleteAccountWithNoOpportunities() { // Test data setup // Create one account with no opportunities by calling a utility method Account[] accts = TestDataFactory.createAccountsWithOpps(1,0); // Perform test Test.startTest(); Database.DeleteResult result = Database.delete(accts[0], false); Test.stopTest(); // Verify that the deletion was successful System.assert(result.isSuccess()); } @isTest static void TestDeleteBulkAccountsWithOneOpportunity() { // Test data setup // Create accounts with one opportunity each by calling a utility method Account[] accts = TestDataFactory.createAccountsWithOpps(200,1); // Perform test Test.startTest(); Database.DeleteResult[] results = Database.delete(accts, false); Test.stopTest(); // Verify for each record. // In this case the deletion should have been stopped by the trigger, // so check that we got back an error. for(Database.DeleteResult dr : results) { System.assert(!dr.isSuccess()); System.assert(dr.getErrors().size() > 0); System.assertEquals('Cannot delete account with related opportunities.', dr.getErrors()[0].getMessage()); } } @isTest static void TestDeleteBulkAccountsWithNoOpportunities() { // Test data setup // Create accounts with no opportunities by calling a utility method Account[] accts = TestDataFactory.createAccountsWithOpps(200,0); // Perform test Test.startTest(); Database.DeleteResult[] results = Database.delete(accts, false); Test.stopTest(); // For each record, verify that the deletion was successful for(Database.DeleteResult dr : results) { System.assert(dr.isSuccess()); } } }
Executar todos os métodos de teste
O passo final é executar os métodos de teste em nossa classe de teste, agora que a classe contém testes mais abrangentes e foi refatorada para utilizar uma fábrica de dados de teste. Como você já executou os testes na classe TestAccountDeletion
, você pode simplesmente executar novamente essa classe de teste para executar todos os seus métodos de teste.
- Para executar o mesmo teste, clique na guia Tests (Testes), selecione o teste a ser executado e, em seguida, clique em Test (Teste) | Rerun (Executar novamente).
- Verifique os resultados na guia Tests (Testes), expandindo a última execução de teste. A execução de teste deve informar que todos os quatro testes foram aprovados!
Recursos