Rocoder
Rocoder

Reputation: 1103

Springboot unittest when applicationcontext initialize based on environment value from application.properties

I have a working spring boot application and adding unit tests now. I am trying to write a unit test for the Service layer which has two possible handlers. At a time any one of the handlers will be active based on deployment of the service.

My code looks like below.

Config-

package com.org.app.configs;

@Configuration
public class DeploymentFactoryManager {
    @Value("${deployment:}")
    private String deploymentEnv;

    @Autowired
    ApplicationContext ctx;

    @Bean
    public IDeploymentHandler getDeploymentInterface() throws InvalidConfigException {
        IDeploymentHandler deploymentHandler = null;
        if(deploymentEnv.equalsIgnoreCase("kubernetes")){
            deploymentHandler = ctx.getBean(KubernetesDeployHandler.class);
        }else if(deploymentEnv.equalsIgnoreCase("docker")){
            deploymentHandler =  ctx.getBean(DockerDeployHandler.class);
        } else {
            throw new InvalidConfigException("Unknown queue type : "+deploymentEnv);
        }
        return deploymentHandler;
    }
}

Service-

package com.org.app.services;

public List<String> status() throws InvalidConfigException{
        
    @Autowired
    DeploymentFactoryManager deploymentFactoryManager;
        
    public List<String> getStatus(){
        IDeploymentHandler iDeploymentHandler = deploymentFactoryManager.getDeploymentInterface();
        return iDeploymentHandler.list();
    }

I am facing an issue while writing unit tests. So far I have already tried with ReflectionTestUtils to set the field but it fails with the message Either target object or target class for the field must be specified. I tried with @TestPropertySource but that also doesn't seem to work. Code doesn't seem unit test friendly.

@BeforeAll
    public static void setup(){
        ReflectionTestUtils.setField(deploymentFactoryManager, "deploymentEnv", "kubernetes");
    }

Any suggestion would be appreciated?

Upvotes: 1

Views: 371

Answers (1)

Christian Ullenboom
Christian Ullenboom

Reputation: 1458

As a side note: You make your code easier to test if you inject every dependency, like:

public IDeploymentHandler getDeploymentInterface( @Value("${deployment:}") String deploymentEnv, ApplicationContext ctx ) throws InvalidConfigException {

In general, it's not a good strategy to get beans out of the context; it's the opposite of the Spring idea: tell what u want and don't ask for it.

Upvotes: 1

Related Questions