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.

terrabl
  • 743
  • 3
  • 8
  • 23
  • Does this answer your question? [Spring @Value TypeMismatchException:Failed to convert value of type 'java.lang.String' to required type 'java.lang.Double'](https://stackoverflow.com/questions/42733067/spring-value-typemismatchexceptionfailed-to-convert-value-of-type-java-lang-s) – tgdavies Feb 03 '23 at 23:15
  • That code is not a part of a repo that I can alter. – terrabl Feb 06 '23 at 04:51

0 Answers0