You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

测试SobjectByParams类遇异常,测试覆盖率未达标

Apex测试异常与覆盖率不足问题解决

问题描述

测试执行时抛出异常 SobjectByParams.InvalidTypeNameException: invalidSobjectNameError,且当前测试覆盖率仅53.33%,无法满足最低80%的要求。

原代码

主类 SobjectByParams

public with sharing class SobjectByParams {
    public SObject createSObject(String sObjectName, Map<String, String> fields) {

        String invalidSObjectError = System.Label.invalid_Sobject_Name;
        String invalidFieldError = System.Label.Invalid_Sobject_Field;

        SObject newObject;
        try {
            newObject = (SObject) Type.forName(sObjectName).newInstance();
        } catch (NullPointerException ex) {
            throw new InvalidTypeNameException(invalidSObjectError);
        }

        for (String field : fields.keySet()) {
            try {
                newObject.put(field, fields.get(field));
            } catch (SObjectException ex) {
                throw new InvalidTypeNameException(invalidFieldError);
            }
        }

        insert newObject;
        return newObject;
    }

    public class InvalidTypeNameException extends Exception {
    }
}

测试类 SobjectByParamsTest

@IsTest
public with sharing class SobjectByParamsTest {

    SobjectByParams sobjectByParams;

    private static final String TestName = 'TestName';
    private static final String BCity = 'Lviv';
    private static final String LastName = 'Kapo';
    private static final String Email = 'email';

    @IsTest
    static void createSObject() {
        SobjectByParams sobjectByParams = new SobjectByParams();
        Map<String, String> fields = new Map<String, String>();
        fields.put('BillingCity', BCity);
        Test.startTest();
        SObject result = sobjectByParams.createSObject(TestName, fields);
        Test.stopTest();
        System.assertEquals(BCity, result.get(BCity));
    }
}

问题分析

  1. 测试异常原因:测试中使用'TestName'作为对象名称,这不是Salesforce中存在的标准或自定义对象API名称,Type.forName(sObjectName)返回null,触发NullPointerException,进而抛出自定义异常。
  2. 覆盖率不足原因:当前测试仅覆盖了正常创建对象的分支,未覆盖无效对象名、无效字段名这两个异常分支,导致大量代码未被执行。

解决方案

修改测试类,使用真实存在的对象(如标准对象Account),并添加异常场景测试,覆盖所有代码路径:

修改后的测试类

@IsTest
public with sharing class SobjectByParamsTest {

    private static final String ACCOUNT_OBJECT_NAME = 'Account';
    private static final String INVALID_OBJECT_NAME = 'TestName';
    private static final String BILLING_CITY_FIELD = 'BillingCity';
    private static final String BILLING_CITY_VALUE = 'Lviv';
    private static final String INVALID_FIELD_NAME = 'Invalid_Field__c';

    @IsTest
    static void createValidSObject_Success() {
        SobjectByParams sobjectByParams = new SobjectByParams();
        Map<String, String> fields = new Map<String, String>();
        fields.put(BILLING_CITY_FIELD, BILLING_CITY_VALUE);
        
        Test.startTest();
        SObject result = sobjectByParams.createSObject(ACCOUNT_OBJECT_NAME, fields);
        Test.stopTest();
        
        // 修正断言:用字段名而非字段值获取字段内容
        System.assertEquals(BILLING_CITY_VALUE, result.get(BILLING_CITY_FIELD));
    }

    @IsTest
    static void createSObject_InvalidObjectName_ThrowsException() {
        SobjectByParams sobjectByParams = new SobjectByParams();
        Map<String, String> fields = new Map<String, String>();
        
        Test.startTest();
        try {
            sobjectByParams.createSObject(INVALID_OBJECT_NAME, fields);
            System.assert(false, '预期抛出InvalidTypeNameException,但未抛出');
        } catch (SobjectByParams.InvalidTypeNameException ex) {
            System.assertEquals(System.Label.invalid_Sobject_Name, ex.getMessage());
        }
        Test.stopTest();
    }

    @IsTest
    static void createSObject_InvalidFieldName_ThrowsException() {
        SobjectByParams sobjectByParams = new SobjectByParams();
        Map<String, String> fields = new Map<String, String>();
        fields.put(INVALID_FIELD_NAME, 'test');
        
        Test.startTest();
        try {
            sobjectByParams.createSObject(ACCOUNT_OBJECT_NAME, fields);
            System.assert(false, '预期抛出InvalidTypeNameException,但未抛出');
        } catch (SobjectByParams.InvalidTypeNameException ex) {
            System.assertEquals(System.Label.Invalid_Sobject_Field, ex.getMessage());
        }
        Test.stopTest();
    }
}

修改说明

  • 替换无效对象名为标准对象Account,确保Type.forName能正常实例化对象
  • 添加两个异常测试方法,分别验证无效对象名和无效字段名场景下的异常抛出逻辑
  • 修正原测试中的断言错误:原代码用字段值BCity作为键获取字段,应改为用字段名BillingCity
  • 所有分支逻辑均被覆盖,测试覆盖率将提升至100%

内容的提问来源于stack exchange,提问作者Pavlo Fedyk

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.04 23:55:30