Skip to content

Accept SDK API clients as constructor parameters for improved testability #36

Description

@Schmarvinius

Summary

Allow AICoreServiceImpl to receive SDK API clients via constructor injection, improving unit testability without requiring environment-level mocking.

Problem

AICoreServiceImpl directly instantiates SDK clients in its constructor:

public AICoreServiceImpl(String name, CdsRuntime runtime, boolean multiTenancyEnabled) {
  // ...
  this.deploymentApi = new DeploymentApi();
  this.configurationApi = new ConfigurationApi();
  this.resourceGroupApi = new ResourceGroupApi();
  this.sdkService = new AiCoreService();
}

This couples the class to the runtime SDK environment. Unit tests currently must mock at the AICoreServiceImpl level (mocking getDeploymentApi() etc.) rather than injecting mocked clients directly.

In cds-services, external clients are injected or factory-created (e.g., RemoteODataHandler receives HttpClient from context).

Plan

Step 1: Add Overloaded Constructor

public AICoreServiceImpl(
    String name, CdsRuntime runtime, boolean multiTenancyEnabled,
    DeploymentApi deploymentApi, ConfigurationApi configurationApi,
    ResourceGroupApi resourceGroupApi, AiCoreService sdkService) {
  super(name, runtime);
  this.multiTenancyEnabled = multiTenancyEnabled;
  // ... read config properties ...
  this.deploymentApi = deploymentApi;
  this.configurationApi = configurationApi;
  this.resourceGroupApi = resourceGroupApi;
  this.sdkService = sdkService;
}

Step 2: Keep Convenience Constructor

public AICoreServiceImpl(String name, CdsRuntime runtime, boolean multiTenancyEnabled) {
  this(name, runtime, multiTenancyEnabled,
       new DeploymentApi(), new ConfigurationApi(),
       new ResourceGroupApi(), new AiCoreService());
}

Step 3: Simplify Unit Tests

// Before: tests mock via when(service.getDeploymentApi()).thenReturn(mockApi)
// After: pass mocks directly
var service = new AICoreServiceImpl(name, runtime, false,
    mockDeploymentApi, mockConfigurationApi, mockResourceGroupApi, mockSdkService);

Files

  • AICoreServiceImpl.java (add constructor overload, refactor existing constructor to delegate)
  • AICoreServiceImplTest.java (optional: simplify mocking setup)
  • Handler tests (optional: can continue using current pattern since handlers receive the service instance)

Risk

None. The existing constructor remains unchanged — this is purely additive. No breaking changes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions