Skip to content

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

@Schmarvinius

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
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions