Skip to main content
Trailblazer Community 现已在 Slack 开启公开测试版。欢迎加入并实时交流。加入 Slack

为 Apex 测试创建测试数据

学习目标

完成本单元后,您将能够:

  • 创建测试实用程序类。
  • 使用测试实用程序方法为各种测试个案建立测试数据。
  • 在同一个类中执行所有测试方法。
  • 使用测试实用程序类为建立测试数据添加可重用的方法。
备注

备注

用中文(简体)学习?在中文(简体)Trailhead Playground 中开始挑战,用括号中提供的译文完成挑战。仅复制并粘贴英文值,因为挑战验证基于英文数据。如果在中文(简体)组织中没有成功通过挑战,我们建议您 (1) 将区域设置切换为美国,(2) 按此处说明将语言切换为英文,(3) 再次单击“检查挑战”按钮。

查看 Trailhead 本地化语言徽章详细了解如何利用 Trailhead 译文。

先决条件

如果您还未完成上一个单元的先决条件,即测试 Apex 触发器,请先完成。

添加测试实用程序类

通过调用实用程序类方法替换创建的测试数据,以重构之前的测试方法。首先,您需要创建测试实用程序类。

TestDataFactory 类是一个用 @IsTest 注释的公共类,只能从正在运行的测试中访问。测试实用程序类包含测试方法可以调用的方法,用来执行实用的任务,例如建立测试数据。测试实用程序类不受组织的代码大小限制。

添加 TestDataFactory 类:

  1. 在 Web Console(Web 控制台)中,按 Ctrl+Shift+P (Windows) 或 ⌘+Shift+P (macOS) 打开命令面板。
  2. 输入 SFDX: Create Apex Class(SFDX:创建 Apex 类),然后按 Enter 键。
  3. 对于模板类型,请选择 DefaultApexClass,然后按 Enter 键。
  4. 对于类名称,请输入 TestDataFactory,然后按 Enter 键。
  5. 对于输出目录,请选择 force-app/main/default/classes,然后按 Enter 键。
  6. 将默认类主体替换为以下内容。
@IsTest
public with sharing 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 as user 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 as user opps;
    return accts;
  }
}

此测试实用程序类包含一种静态方法 createAccountsWithOpps(),该方法接受 numAccts 参数中持有的客户数量以及 numOppsPerAcct 参数中为每一个客户创建的关联业务机会。该方法中的第一个循环创建了指定数量的客户,并将其保存在 accts 列表变量中。在第一个循环之后,调用 insert DML 语句以创建数据库列表中的所有客户。

通过第二个循环创建了业务机会。由于每组业务机会都链接至同一个客户,所以外循环遍历了所有客户,并包含为当前客户创建相关业务机会的嵌套循环。下次运行嵌套循环时,使用 add() 方法将业务机会添加到同一个列表中。通过 AccountId 字段将业务机会链接至其父客户。创建的所有业务机会总数是业务机会数量与客户数量的乘积 (numOppsPerAcct*numAccts)。接下来,在循环外有效调用 insert DML 语句,实现在单次调用中为所有客户创建集合中的所有业务机会。

最后,该方法返回新客户列表。

Note

即使该方法不返回关联的业务机会,您仍然可以通过编写 SOQL 查询来获取这些记录,该查询利用了客户和业务机会之间的现有关系,例如测试 Apex 触发器中触发器使用的查询。

调用实用程序方法,创建测试数据

现在您已经添加了测试实用程序类,请修改 TestAccountDeletion 测试类以使用这个类。TestDataFactory.createAccountsWithOpps(1,1) 调用返回的数组包含一个客户 sObject。

这是修改后的测试方法。

@IsTest
private with sharing 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, AccessLevel.USER_MODE);
    Test.stopTest();
    // Verify that the deletion should have been stopped by the trigger,
    // so check 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());
  }
}

测试不同条件

一种测试方法不足以测试触发器所有可能的输入。我们需要测试一些其他条件,例如删除没有业务机会的客户时。我们还需要使用大量记录而不是单个记录来测试相同的场景。以下是包含三个附加测试方法的新版测试类。保存更新版本的类。

@IsTest
private with sharing 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, AccessLevel.USER_MODE);
    Test.stopTest();
    // Verify that the deletion should have been stopped by the trigger,
    // so check 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());
  }
  @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, AccessLevel.USER_MODE);
    Test.stopTest();
    // Verify that the deletion was successful
    Assert.isTrue(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, AccessLevel.USER_MODE);
    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) {
      Assert.isFalse(dr.isSuccess());
      Assert.isTrue(dr.getErrors().size() > 0);
      Assert.areEqual('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, AccessLevel.USER_MODE);
    Test.stopTest();
    // For each record, verify that the deletion was successful
    for(Database.DeleteResult dr : results) {
      Assert.isTrue(dr.isSuccess());
    }
  }
}

运行所有测试方法

最后一步是在测试类中运行测试方法,现在该类包含了更全面的测试,并已重构为使用测试数据工厂。

  1. 在 Web Console(Web 控制台)中,点击 Activity Bar(活动栏)中的 测试图标。Testing(测试)侧面板随即打开。
  2. 在 Testing(测试)搜索栏中,输入 TestAccountDeletion。
  3. 要运行类中的所有测试方法,将鼠标悬停在 TestAccountDeletion 行上,然后点击 运行测试图标。
  4. 在 Test Results(测试结果)面板中查看结果。测试运行应该报告所有四个测试都已通过!

资源

在 Salesforce 帮助中分享 Trailhead 反馈

我们很想听听您使用 Trailhead 的经验——您现在可以随时从 Salesforce 帮助网站访问新的反馈表单。

了解更多 继续分享反馈