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

Apex中如何为OrderSummary等生成对象编写单元测试?

核心前提

OrderSummary是Salesforce Order Management模块的系统托管对象,默认测试上下文既不支持直接DML插入,也不会自动触发生成,ConnectApi相关操作也要求开启SeeAllData违反测试隔离原则,最优解是通过依赖注入+Mock层绕开真实数据库查询,具体实现方案如下:


方案1:依赖注入+静态Mock实现(最推荐,符合Apex测试最佳实践)
  • 第一步:抽离OrderSummary查询逻辑到单独服务类,同时定义对应接口,示例代码:
// 定义服务接口
public interface IOrderSummaryService {
    List<OrderSummary> getByOrderId(Id orderId);
}

// 真实业务实现类
public class OrderSummaryServiceImpl implements IOrderSummaryService {
    public List<OrderSummary> getByOrderId(Id orderId) {
        return [SELECT Id, OrderId, TotalAmount FROM OrderSummary WHERE OrderId = :orderId];
    }
}
  • 第二步:业务代码依赖接口而非具体实现,通过构造方法/工厂类注入实现类:
public class OrderBusinessService {
    private IOrderSummaryService summaryService;
    // 默认用真实实现,测试时可传入mock实现
    public OrderBusinessService() {
        this.summaryService = new OrderSummaryServiceImpl();
    }
    public OrderBusinessService(IOrderSummaryService mockService) {
        this.summaryService = mockService;
    }
    // 你的业务方法,直接调用summaryService的查询方法即可
}
  • 第三步:测试时实现自定义Mock类,返回你构造的测试数据,无需访问真实数据库:
// 测试用Mock实现类
@isTest
public class MockOrderSummaryService implements IOrderSummaryService {
    private List<OrderSummary> mockData;
    public MockOrderSummaryService(List<OrderSummary> mockData) {
        this.mockData = mockData;
    }
    public List<OrderSummary> getByOrderId(Id orderId) {
        return mockData;
    }
}

// 测试用例示例
@isTest
private static void testOrderSummaryLogic() {
    // 构造你需要的假OrderSummary数据
    List<OrderSummary> mockSummaries = new List<OrderSummary>();
    OrderSummary mockSum = new OrderSummary(
        OrderId = '00kxxxxxxx', // 替换为你测试用的OrderId
        TotalAmount = 1000.00
    );
    mockSummaries.add(mockSum);
    // 注入mock实现到业务类
    OrderBusinessService businessService = new OrderBusinessService(new MockOrderSummaryService(mockSummaries));
    // 后续直接调用业务方法测试即可,不需要真实存在OrderSummary数据
}

方案2:使用Apex Stub API动态Mock(无需单独写Mock类)

如果不想额外创建Mock实现类,可以用Salesforce自带的Stub API动态指定方法返回值,适合方法较多的场景,示例代码:

@isTest
public class MockProvider implements System.StubProvider {
    private Map<String, Object> methodReturnMap;
    public MockProvider(Map<String, Object> returnMap) {
        this.methodReturnMap = returnMap;
    }
    public Object handleMethodCall(Object stubbedObject, String stubbedMethodName, Type returnType, List<Type> listOfParamTypes, List<String> listOfParamNames, List<Object> listOfArgs) {
        return methodReturnMap.get(stubbedMethodName);
    }
}

// 测试用例中使用
@isTest
private static void testDynamicMock() {
    List<OrderSummary> mockSummaries = new List<OrderSummary>{new OrderSummary(TotalAmount = 1000)};
    Map<String, Object> returnMap = new Map<String, Object>{'getByOrderId' => mockSummaries};
    IOrderSummaryService mockService = (IOrderSummaryService)Test.createStub(IOrderSummaryService.class, new MockProvider(returnMap));
    OrderBusinessService businessService = new OrderBusinessService(mockService);
    // 后续执行业务测试
}

临时应急方案:测试上下文判断返回Mock数据

如果暂时没有时间重构代码抽离服务类,可以在查询逻辑中增加测试上下文判断,直接返回构造的测试数据,该方案侵入性较强,仅建议临时使用:

public List<OrderSummary> getOrderSummaries(Id orderId) {
    // 测试上下文直接返回mock数据
    if(Test.isRunningTest()) {
        return new List<OrderSummary>{new OrderSummary(OrderId = orderId, TotalAmount = 1000)};
    }
    // 生产环境执行真实查询
    return [SELECT Id, TotalAmount FROM OrderSummary WHERE OrderId = :orderId];
}

内容的提问来源于stack exchange,提问作者Jason C

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.19 19:24:05