Home > Mobile >  How do I create unit test for configuration class with properties?
How do I create unit test for configuration class with properties?

Time:11-09

I am trying to create unit test for configuration class for connection class. Here is my config class for connection:

@Configuration
public class JmsMessageGatewayConnectionConfig {

    @Bean
    public JmsMessageGatewayConnection jmsMessageGatewayConnection (final JmsMessageGatewayProperties jmsConfig) throws JMSException {
        return new JmsMessageGatewayConnection(jmsConfig, cachingConnectionFactory(jmsConfig));
    }

    private CachingConnectionFactory cachingConnectionFactory(final JmsMessageGatewayProperties jmsConfig) {
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
        cachingConnectionFactory.setTargetConnectionFactory(jmsConnectionFactory(jmsConfig));
        cachingConnectionFactory.resetConnection();
        return cachingConnectionFactory;
    }

    private JmsConnectionFactory jmsConnectionFactory(final JmsMessageGatewayProperties jmsConfig) {
        JmsConnectionFactory jmsConnectionFactory =
                new JmsConnectionFactory(jmsConfig.getUsername(), jmsConfig.getPassword(), jmsConfig.getRemoteUri());
        jmsConnectionFactory.setReceiveLocalOnly(true);
        return jmsConnectionFactory;
    }

    @Bean
    @ConfigurationProperties(prefix = "jms")
    public JmsMessageGatewayProperties messageGatewayProperties() {
        return new JmsMessageGatewayProperties();
    }
}

And here is JmsMessageGatewayProperties class:

public class JmsMessageGatewayProperties {

    private String remoteUri;
    private String username;
    private String password;
    private boolean messagePersistent;
    private Integer forceDetachedRetryLimit = 1;

    public String getRemoteUri() {
        return remoteUri;
    }

    public void setRemoteUri(final String remoteUri) {
        this.remoteUri = remoteUri;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(final String username) {
        this.username = username;
    }

    public String getPassword() {
        return password;
    }

    public void setPassword(final String password) {
        this.password = password;
    }

    public boolean isMessagePersistent() {
        return messagePersistent;
    }

    public void setMessagePersistent(final boolean messagePersistent) {
        this.messagePersistent = messagePersistent;
    }

    public Integer getForceDetachedRetryLimit() {
        return forceDetachedRetryLimit;
    }

    public void setForceDetachedRetryLimit(final Integer forceDetachedRetryLimit) {
        this.forceDetachedRetryLimit = forceDetachedRetryLimit;
    }
}

And here is my test class:

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = { JmsMessageGatewayConnectionConfig.class})
@TestPropertySource(locations = "classpath:camel.properties")
public class JmsMessageGatewayConnectionConfigTest {

    @Autowired
    private JmsMessageGatewayConnection jmsMessageGatewayConnection;

    @Test
    public void jmsMessageGatewayConnectionConfigTest() {
        Assert.assertNotNull(jmsMessageGatewayConnection);
    }
}

Test fails with Invalid URI: cannot be null or empty. I think I understand that properties in jmsConfig are null via checking it in debug mode. I did update my camel.properties to have the properties like this:

jms.remoteUri=vm://localhost:61616
jms.username=username
jms.password=password

I am not sure what I am missing here. Why are the properties inside of JmsMessageGatewayProperties null even though it has the object?

CodePudding user response:

Have you tried added @DependsOn since the implementation does require the configuration properties to exist first? @DependsOn allows you to define dependencies of a bean before it can be created.

Also, it depends on which version of spring you are using. Are you using spring-boot?

Or define the properties reference in the class.

@PropertySource("classpath:camel.properties")
public class JmsMessageGatewayProperties  {}

There were changes to spring that allowed the following:

@ConfigurationPropertiesScan 
@ConfigurationProperties(prefix = "jms")
public JmsMessageGatewayProperties messageGatewayProperties() {
    return new JmsMessageGatewayProperties();
}

CodePudding user response:

I don't know why but definig the bean annotated with @ConfigurationProperties in the @Configuration class

@Bean
@ConfigurationProperties(prefix = "jms")
public JmsMessageGatewayProperties messageGatewayProperties() {
    return new JmsMessageGatewayProperties();
}

gives this error in the test:

Caused by: java.lang.IllegalStateException: No ConfigurationProperties annotation found on 'com.example.springbootconsumer.JmsMessageGatewayProperties'.

Test Class:

import static org.junit.jupiter.api.Assertions.assertNotNull;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestPropertySource;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@ExtendWith(SpringExtension.class)
@EnableConfigurationProperties(value = JmsMessageGatewayProperties.class)
@ContextConfiguration(classes = JmsMessageGatewayConnectionConfig.class)
@TestPropertySource(locations = "classpath:camel.properties")
public class JmsMessageGatewayConnectionConfigTest {

    @Autowired
    private JmsMessageGatewayProperties jmsMessageGatewayProperties;

    @Test
    public void jmsMessageGatewayConnectionConfigTest() {
        assertNotNull(jmsMessageGatewayProperties);
    }
}

A possible workaround is to define the bean for the properties like this:

@Configuration
@ConfigurationProperties(prefix = "jms")
public class JmsMessageGatewayProperties {
    
    private String remoteUri;
    private String username;
    private String password;
    private boolean messagePersistent;
    private Integer forceDetachedRetryLimit = 1;
    //getters setters
}

and inject it in the configuration class:

@Configuration
public class JmsMessageGatewayConnectionConfig {
    @Autowired
    private JmsMessageGatewayProperties jmsConfig;
    @Bean
    public JmsMessageGatewayConnection jmsMessageGatewayConnection () throws JMSException {
        return new JmsMessageGatewayConnection(jmsConfig, cachingConnectionFactory(jmsConfig));
    }

    private CachingConnectionFactory cachingConnectionFactory() {
        CachingConnectionFactory cachingConnectionFactory = new CachingConnectionFactory();
        cachingConnectionFactory.setTargetConnectionFactory(jmsConnectionFactory(jmsConfig));
        cachingConnectionFactory.resetConnection();
        return cachingConnectionFactory;
    }

    private JmsConnectionFactory jmsConnectionFactory() {
        JmsConnectionFactory jmsConnectionFactory =
                new JmsConnectionFactory(jmsConfig.getUsername(), jmsConfig.getPassword(), jmsConfig.getRemoteUri());
        jmsConnectionFactory.setReceiveLocalOnly(true);
        return jmsConnectionFactory;
    }
}

Test class:

@ExtendWith(SpringExtension.class)
@EnableConfigurationProperties(value = JmsMessageGatewayProperties.class)
@ContextConfiguration(classes = JmsMessageGatewayConnectionConfig.class)
@TestPropertySource(locations = "classpath:camel.properties")
public class JmsMessageGatewayConnectionConfigTest {

    @Autowired
    private JmsMessageGatewayConnection jmsMessageGatewayConnection;

    @Test
    public void jmsMessageGatewayConnectionConfigTest() {
        Assert.assertNotNull(jmsMessageGatewayConnection);
    }
}

using spring-boot 2.7.3 Hope this helps

  • Related