为 Apex 测试创建测试数据
学习目标
完成本单元后,您将能够:
- 创建测试实用程序类。
- 使用测试实用程序方法为各种测试个案建立测试数据。
- 在同一个类中执行所有测试方法。
为 Apex 测试创建测试数据
使用测试实用程序类为建立测试数据添加可重用的方法。
先决条件
如果您还未完成上一个单元的先决条件,即测试 Apex 触发器,请先完成。
添加测试实用程序类
通过调用实用程序类方法替换创建的测试数据,以重构之前的测试方法。首先,您需要创建测试实用程序类。
TestDataFactory 类是一个用 @isTest 注释的公共类,只能从正在运行的测试中访问。测试实用程序类包含测试方法可以调用的方法,用来执行实用的任务,例如建立测试数据。测试实用程序类不受组织的代码大小限制。
添加 TestDataFactory 类:
- 在 Developer Console 中,单击 File(文件)| New(新建)| Apex Class(Apex 类),并输入
TestDataFactory作为类名,然后单击 OK(确定)。 - 将默认类主体替换为以下内容。
@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; } }
此测试实用程序类包含一种静态方法 createAccountsWithOpps(),该方法接受 numAccts 参数中持有的客户数量以及 numOppsPerAcct 参数中为每一个客户创建的关联业务机会。该方法中的第一个循环创建了指定数量的客户,并将其保存在 accts 列表变量中。在第一个循环之后,调用 insert() DML 语句以创建数据库列表中的所有客户。
通过第二个循环创建了业务机会。由于每组业务机会都链接至同一个客户,所以外循环遍历了所有客户,并包含为当前客户创建相关业务机会的嵌套循环。下次运行嵌套循环时,使用 add() 方法将业务机会添加到同一个列表中。通过 AccountId 字段将业务机会链接至其父客户。创建的所有业务机会总数是业务机会数量与客户数量的乘积 (numOppsPerAcct*numAccts)。接下来,在循环外有效调用 insert() DML 语句,实现在单次调用中为所有客户创建集合中的所有业务机会。
最后,该方法返回新客户列表。
调用实用程序方法,创建测试数据
现在您已经添加了测试实用程序类,请修改 TestAccountDeletion 测试类以使用这个类。TestDataFactory.createAccountsWithOpps(1,1) 调用返回的数组包含一个客户 sObject。
这是修改后的测试方法。
@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
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());
}
}
}运行所有测试方法
最后一步是在测试类中运行测试方法,现在该类包含了更全面的测试,并已重构为使用测试数据工厂。您已经在 TestAccountDeletion 类中运行了测试,您只需重新运行此测试类即可运行其所有测试方法。
- 要执行相同的测试,请单击 Tests(测试)选项卡,选择您的测试运行,然后依次单击 Test(测试)| Rerun(重新运行)。
- 通过展开最新的测试运行,检查 Tests(测试)选项卡中的结果。测试运行应该报告所有四个测试都已通过!
资源
