Creare dati di test per i test Apex
Obiettivi di apprendimento
Al completamento di questa unità, sarai in grado di:
- Creare una classe di utilità per l'esecuzione di test.
- Utilizzare un metodo di utilità per l'esecuzione di test al fine di impostare i dati per i vari casi di test.
- Eseguire tutti i metodi di test di una classe.
Creare dati di test per i test Apex
Utilizza le classi di utilità per l'esecuzione di test al fine di aggiungere metodi riutilizzabili da impiegare nell'impostazione dei dati di test.
Prerequisiti
Se non l'hai già fatto, completa i prerequisiti dell'unità precedente, Testare i trigger Apex.
Aggiungere una classe di utilità per l'esecuzione di test
Rifattorizziamo il metodo di test precedente sostituendo la creazione dei dati di test con una chiamata a un metodo per la classe di utilità. Per prima cosa, è necessario creare la classe di utilità per l'esecuzione di test.
La classe TestDataFactory
è un tipo speciale di classe: è una classe pubblica che è annotata con @isTest
e a cui si può accedere solo da un test in esecuzione. Le classi di utilità per l'esecuzione di test contengono metodi richiamabili dai metodi di test per eseguire attività utili, come l'impostazione dei dati di test. Le classi di utilità per l'esecuzione di test sono escluse dal limite di dimensioni del codice dell'organizzazione.
Per aggiungere la classe TestDataFactory
:
- Nella Developer Console, fai clic su File | New (Nuovo) | Apex Class (Classe Apex) e inserisci
TestDataFactory
come nome della classe, quindi fai clic su OK. - Sostituisci il corpo predefinito della classe con il codice seguente.
@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; } }
Questa classe di utilità per l'esecuzione di test contiene un metodo statico, createAccountsWithOpps()
, che accetta il numero di account (contenuto nel parametro numAccts
) e il numero di opportunità correlate da creare per ciascun account (contenuto nel parametro numOppsPerAcct
). Il primo loop del metodo crea gli account nella quantità specificata e li memorizza nella variabile elenco accts
. Dopo il primo loop, viene chiamata l'istruzione DML insert()
per creare tutti gli account dell'elenco nel database.
Il secondo loop crea le opportunità. Poiché ciascun gruppo di opportunità è collegato a un account, il loop esterno esegue l'iterazione sugli account e contiene un loop nidificato che crea opportunità correlate per l'account corrente. Con l'esecuzione successiva del loop nidificato, le opportunità vengono aggiunte allo stesso elenco tramite il metodo add()
. Le opportunità sono collegate agli account padre mediante il campo AccountId
. Il numero totale di tutte le opportunità create è il prodotto del numero di opportunità per il numero di account (numOppsPerAcct
*numAccts
). Quindi, l'istruzione DML insert()
viene chiamata in modo efficiente al di fuori del loop per creare tutte le opportunità della raccolta per tutti gli account in un'unica chiamata.
Per finire, questo metodo restituisce un elenco dei nuovi account.
Chiamare i metodi di utilità per la creazione dei dati di test
Adesso che hai aggiunto la classe di utilità per l'esecuzione di test, modifica la classe di test TestAccountDeletion
in modo da poterla sfruttare. L'array restituita dalla chiamata TestDataFactory.createAccountsWithOpps(1,1)
contiene un sObject Account.
Ecco il metodo di test modificato. È una versione più breve.
@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()); } }
Test per condizioni diverse
Un solo metodo di test non è sufficiente per verificare tutti i possibili input per il trigger. È necessario eseguire dei test su altre condizioni, ad esempio quando un account senza opportunità viene eliminato. È necessario eseguire test sugli stessi scenari con un numero di record in blocco anziché con un singolo record. Ecco una versione aggiornata della classe di test che contiene i tre metodi di test aggiuntivi. Salva questa versione aggiornata della 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()); } } }
Eseguire tutti i metodi di test
Il passaggio finale consiste nell'eseguire i metodi di test nella classe di test, adesso che la classe contiene test più completi e che è stata rifattorizzata per utilizzare una data factory per i test. Dato che hai già eseguito i test della classe TestAccountDeletion
, puoi semplicemente rieseguire questa classe di test per eseguirne tutti i metodi.
- Per eseguire lo stesso test, fai clic sulla scheda Tests (Test), seleziona l'esecuzione del test desiderata e poi fai clic su Test | Rerun (Esegui nuovamente).
- Controlla i risultati nella scheda Tests (Test) espandendo l'ultimo test eseguito. L'esecuzione del test dovrebbe riportare che tutti e quattro i test sono stati superati.
Risorse
- Apex Developer Guide: Common Test Utility Classes for Test Data Creation (Guida per gli sviluppatori Apex: Classi di utilità per l'esecuzione di test comuni per la creazione di dati di test)