Empiece a realizar un seguimiento de su progreso
Inicio de Trailhead
Inicio de Trailhead

Crear datos de prueba para pruebas de Apex

Objetivos de aprendizaje

Después de completar esta unidad, podrá:
  • Crear una clase de utilidad de prueba.
  • Usar un método de utilidad de prueba para configurar datos de prueba para varios casos de prueba.
  • Ejecutar todos los métodos de una clase.

Crear datos de prueba para pruebas de Apex

Use clases de utilidad de prueba para agregar métodos reutilizables para la configuración de datos de prueba.

Requisitos

Confirme que cumple los requisitos de la unidad anterior (Pruebas de desencadenadores de Apex) si aún no lo ha hecho.

Adición de una clase de utilidad de prueba

Vamos a refactorizar el método de prueba anterior mediante la sustitución de la creación de datos de prueba por una llamada a un método de clase de utilidad. Primero, debe crear la clase de utilidad de prueba.

La clase TestDataFactory es un tipo de clase especial, ya que es una clase pública que se anota con isTest y a la que se puede acceder desde una prueba en ejecución. Las clases de utilidad de prueba contienen métodos a los que se puede llamar mediante métodos de prueba para realizar tareas útiles, como la configuración de datos de prueba. Las clases de utilidad de prueba se excluyen por lo que respecta al límite de tamaño del código de la organización.

Para agregar la clase TestDataFactory:

  1. En Developer Console, haga clic en File | New | Apex Class (Archivo | Nuevo | Clase de Apex) e ingrese TestDataFactory como nombre de la clase y, a continuación, haga clic en OK (Aceptar).
  2. Sustituya el cuerpo de clase predeterminado por el siguiente.
    @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;
        }
    }

Esta clase de utilidad de prueba contiene un método estático, createAccountsWithOpps(), el cual acepta el número de cuentas (incluido en el parámetro numAccts) y el número de oportunidades relacionadas que crear para cada cuenta (incluido en el parámetro numOppsPerAcct). El primer bucle del método crea el número de cuentas especificado y las almacena en la variable de lista accts. Después del primer bucle, se llama a la declaración DML insert() para crear todas las cuentas de la lista en la base de datos.

El segundo bucle crea las oportunidades. Dado que cada grupo de oportunidades está vinculado a una cuenta, el bucle externo itera en las cuentas y contiene un bucle anidado que crea oportunidades relacionadas para la cuenta actual. La próxima vez que se ejecuta el bucle anidado, las oportunidades se agregan a la misma lista mediante el método add(). Las oportunidades están vinculadas a sus cuentas principales mediante el campo AccountId. El número total de oportunidades creadas es el producto del número de oportunidades con el número de cuentas (numOppsPerAcct*numAccts). A continuación, se llama de forma eficiente a la declaración DML insert() fuera del bucle para crear todas las oportunidades de la colección para todas las cuentas en una sola llamada.

Por último, este método devuelve una lista de cuentas nuevas.

Nota

Nota

Aunque el método no devuelva las oportunidades relacionadas, puede obtener estos registros mediante la escritura de una consulta SOQL que use la relación existente entre la cuenta y la oportunidad, como la consulta usada en el desencadenador de la unidad Pruebas de desencadenadores de Apex.

Llamada a métodos de utilidad para la creación de datos de prueba

Ahora que ya ha agregado la clase de utilidad de prueba, modifique la clase de prueba para aprovechar las ventajas de esta clase. En la clase TestAccountDeletion, sustituya el bloque que empieza por // Test data setup y termina por insert opp; por lo siguiente:

        // Test data setup
        // Create one account with one opportunity by calling a utility method
        Account[] accts = TestDataFactory.createAccountsWithOpps(1,1);

El conjunto devuelto por la llamada a TestDataFactory.createAccountsWithOpps(1,1) contiene un sObject de cuenta.

Este es el método de prueba modificado. Se trata de una versión más 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());
    }        
}

Pruebas de distintas condiciones

Un solo método de prueba no es suficiente para probar todas las entradas posibles para el desencadenador. Debemos probar algunas otras condiciones, como es el caso de la eliminación de una cuenta sin oportunidades. Además, debemos probar los mismos casos con un número masivo de registros en lugar de un solo registro. Esta es una versión actualizada de la clase de prueba que contiene los tres métodos de prueba adicionales. Guarde esta versión actualizada de la clase.

@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());
        }
    }
}

Ejecución de todos los métodos de prueba

El paso final consiste en ejecutar los métodos de prueba de nuestra clase de prueba, ya que ahora la clase contiene pruebas más exhaustivas y se ha refactorizado para el uso de datos de prueba de fábrica. Dado que ya ha ejecutado las pruebas de la clase TestAccountDeletion, puede volver a ejecutar esta clase de prueba para la ejecución de todos sus métodos de prueba.

  1. Para ejecutar la misma ejecución de prueba, haga clic en la ficha Tests (Pruebas), seleccione su ejecución de prueba y haga clic en Test (Prueba) | Rerun (Volver a ejecutar).
  2. Para comprobar los resultados de la ficha Tests (Pruebas), expanda la última prueba ejecutada. La ejecución de la prueba debe indicar que se han superado las cuatro pruebas.