如何为Apex类创建测试类并达成75%测试覆盖率?
提升Apex测试覆盖率到75%+的解决方案
我来帮你梳理下当前测试类的问题,然后给出完整的优化方案,确保覆盖到所有分支逻辑:
原测试类的核心问题
- 测试数据不符合查询条件:你创建的
Account没有设置ShippingLatitude和ShippingLongitude,所以方法里的查询会过滤掉这条记录,导致查询结果为空,部分逻辑的执行情况无法被统计到覆盖率中。 - 未覆盖else分支:原测试只测试了
if分支的几种角色场景,但完全没覆盖不符合if条件的情况(比如用户角色不在白名单里,或者使用的是移动端Theme4t主题),这是覆盖率没到75%的关键原因。 - 用户角色修改逻辑无效:你直接修改内存中的
userDetails对象的UserRoleId,但没有更新到数据库,System.runAs使用的这个对象其实数据库里的角色并没有变化,导致这部分测试逻辑根本没生效。而且依赖组织中已有的UserRole,如果组织里没有这些角色,测试会直接失败。 - 缺少断言验证:只是调用方法但不验证返回结果,既不能保证逻辑正确性,也可能导致部分分支的执行没被正确统计。
优化后的测试类代码
@isTest public class AccountControllerTest { static testMethod void testFindAllCompleteCoverage() { // 1. 创建测试用的UserRole(避免依赖组织现有数据) UserRole yonRole = new UserRole(Name = 'yon'); insert yonRole; UserRole bonRole = new UserRole(Name = 'bon'); insert bonRole; UserRole nonRole = new UserRole(Name = 'non_test'); // 包含'non'关键词 insert nonRole; UserRole goRole = new UserRole(Name = 'go_test'); // 包含'go'关键词 insert goRole; UserRole otherRole = new UserRole(Name = 'other_role'); // 不符合if条件的角色 insert otherRole; // 2. 创建测试用户(不同角色) Profile testProfile = [SELECT Id FROM Profile WHERE Name = 'Standard User' LIMIT 1]; User yonUser = createTestUser(testProfile.Id, yonRole.Id); User bonUser = createTestUser(testProfile.Id, bonRole.Id); User nonUser = createTestUser(testProfile.Id, nonRole.Id); User goUser = createTestUser(testProfile.Id, goRole.Id); User otherUser = createTestUser(testProfile.Id, otherRole.Id); // 3. 创建符合查询条件的Account(设置经纬度) // 属于otherUser的账号(用于测试else分支) Account userAccount = new Account( Name = 'User Owned Account', ShippingLatitude = 40.7128, ShippingLongitude = -74.0060, OwnerId = otherUser.Id ); insert userAccount; // 属于其他用户的账号(用于测试if分支的返回结果) Account publicAccount = new Account( Name = 'Public Account', ShippingLatitude = 34.0522, ShippingLongitude = -118.2437, OwnerId = yonUser.Id ); insert publicAccount; // 4. 测试if分支的各种角色场景(非移动端主题) // 测试yon角色 System.runAs(yonUser) { List<Account> result = AccountController.findAll(); System.assertEquals(2, result.size(), 'Yon角色用户应看到所有符合条件的账号'); } // 测试bon角色 System.runAs(bonUser) { List<Account> result = AccountController.findAll(); System.assertEquals(2, result.size(), 'Bon角色用户应看到所有符合条件的账号'); } // 测试包含non的角色 System.runAs(nonUser) { List<Account> result = AccountController.findAll(); System.assertEquals(2, result.size(), '包含non的角色用户应看到所有符合条件的账号'); } // 测试包含go的角色 System.runAs(goUser) { List<Account> result = AccountController.findAll(); System.assertEquals(2, result.size(), '包含go的角色用户应看到所有符合条件的账号'); } // 5. 测试else分支的场景 // 场景1:角色不符合条件,非移动端主题 System.runAs(otherUser) { List<Account> result = AccountController.findAll(); System.assertEquals(1, result.size(), '其他角色用户应只看到自己的账号'); System.assertEquals(userAccount.Id, result[0].Id, '返回的账号应为用户自己的'); } // 场景2:符合if条件的角色,但使用移动端Theme4t主题 Test.setUiTheme(UserInfo.getUserId(), 'Theme4t'); System.runAs(yonUser) { List<Account> result = AccountController.findAll(); System.assertEquals(1, result.size(), '移动端用户即使角色符合条件,也应只看到自己的账号'); System.assertEquals(publicAccount.Id, result[0].Id, '返回的账号应为用户自己的'); } } // 工具方法:创建测试用户 private static User createTestUser(Id profileId, Id roleId) { User testUser = new User( Alias = 'testusr', Email = 'testuser@example.com', EmailEncodingKey = 'UTF-8', LastName = 'Test', LanguageLocaleKey = 'en_US', LocaleSidKey = 'en_US', ProfileId = profileId, UserRoleId = roleId, TimeZoneSidKey = 'America/Los_Angeles', Username = 'testuser_' + System.currentTimeMillis() + '@example.com' ); insert testUser; return testUser; } }
关键优化点说明
- 独立创建测试数据:自己创建
UserRole和User,完全不依赖组织中的现有数据,测试更稳定。 - 覆盖所有分支:不仅测试
if分支的4种角色情况,还测试了else分支的两种场景(角色不符合、移动端主题),确保所有代码路径都被覆盖。 - 符合查询条件的测试账号:给
Account设置了ShippingLatitude和ShippingLongitude,确保查询能返回结果,让分支逻辑的执行被正确统计。 - 添加断言:每个测试场景都验证了返回结果的数量和正确性,既保证覆盖率,也确保业务逻辑正确。
- 模拟移动端主题:使用
Test.setUiTheme()方法模拟Theme4t主题,覆盖了方法中UserInfo.getUiTheme() != 'Theme4t'的判断逻辑。
这样修改后,你的测试类应该能覆盖到所有代码路径,轻松达到75%以上的覆盖率。
内容的提问来源于stack exchange,提问作者cUser
相关产品推荐
相关产品推荐

