0

I'm attempting to unit test a resilience4j CircuitBreaker, and according to the documentation and my testing, I need to utilize the @SpringBootTest annotation in order to correctly instantiate the circuit breaker for the unit test.

When I attempt to run the unit test I am receiving a UnsatisfiedDependencyException when it tries to instantiate a downstream bean because the value of the property instead of being "true" or "false" is the string value of the property ${boolean.property:true} instead of when I normally run the project manually it is just true.

My unit test is as follows (I am using JUnit 5 and Spring Boot 2.6.6)

@SpringBootTest(classes = Application.class)
class CircuitBreakerTest {

    @MockBean
    private Webservice webservice;

    private final Handler handler = new Handler();

    @Test
    public void testChangeMatrixCircuitBreaker() {

        when(webservice.process(any())).thenThrow(new RuntimeException());

        for (int i = 0; i < 11; i++) {
            // circuit breaker should trip after 10 failures
            ResponseEntity response = handler.processClientRequest("id", "<body/>");
            if (i > 9) {
                assertTrue("CircuitBreaker tripped".equals((String) response.getBody()));
            }
        }
    }
}

Application.java

@SpringBootApplication
@EnableMBeanExport(registration = RegistrationPolicy.IGNORE_EXISTING)
@ImportResource({"classpath:serviceContext.xml"})
@ComponentScan({"application.foundation", "config"})
public class Application {

   private static final Logger LOGGER = LogManager.getLogger(AISApplication.class);

   public static void main(String[] args) {
      SpringApplication.run(AISApplication.class, args);
   }

   @PreDestroy
   public void tearDown() {
      LOGGER.info("PreDestroy - Shutting Down");
   }

}

The bean that is causing the exception is defined inside of the application.foundation component scan. More exactly inside of the resource that it imports.

package application.foundation.security;

@Configuration
@ImportResource({ "classpath:securedClientContext.xml" })
public class OutboundSecurityConfiguration {
    ...
}

securedClientContext.xml (note that I do not have the ability to change this file)

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:util="http://www.springframework.org/schema/util"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
   http://www.springframework.org/schema/util http://www.springframework.org/schema/util/spring-util.xsd">
        <bean id="beanIDontControl" class="bean.i.dont.control.security.BeanIDontControlBean">
           <constructor-arg name="unique" value="${boolean.property:true}" />
        </bean>

</beans>

The stack trace is as follows:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'beanIDontControl' defined in class path resource [securedClientContext.xml]: 
Unsatisfied dependency expressed through constructor parameter 0: Could not convert argument value of type [java.lang.String] to required type [boolean]: 
Failed to convert value of type 'java.lang.String' to required type 'boolean'; nested exception is java.lang.IllegalArgumentException: Invalid boolean value [${boolean.property:true}]

It's failing on line 761 of ContructorResolver

// when i unit test originalValue = ${boolean.property:true} when i run normally it is just true
convertedValue = converter.convertIfNecessary(originalValue, paramType, methodParam);

Does anyone know a way that I could possibly mock or ignore this bean? Maybe even ignore the whole component scale of that security package? I've tried use @TestConfiguration, I've tried everything around @TestPropertySource, I've tried using the property field within @SpringBootTest to manually set the values, no matter what I do I cannot see a change in that property.

2

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.