javapropertiesspring-boot-testspring-contextconditional-on-property

Registering a Bean with multiple different properties to test ConditionalOnProperties


I have a problem in writing a test for verifying that @ConditionalOnProperty is working correctly. I could not find a solution for registering a bean with multiple application properties to find out whether it is creating a bean or not.

The class that should be created as a bean

@Component
@ConditionalOnProperties(prefix = "card.services.connection", value = "baseUrl")
public CardService {

}

I have tried to implement a test through setting a properties via System.setProperty(..);

@SpringBootTest(classes = CardConfiguration.class)
class ContextTest {

  @Autowired
  private ConfigurableApplicationContext context;


  @BeforeEach
  void setUp() {
    System.setProperty("card.services.connection.baseUrl", "http://localhost:8080");
  }

  @Test
  void registerCardBean() {
    context.getBeanFactory().registerSingleton("cardbean", mock(CardService.class));
    boolean tietob2crest = context.containsBeanDefinition("cardbean");
    Assertions.assertTrue(tietob2crest);
  }

}

In this scenario I got failed test. I do not know why, because I set a property, and indicated in annotation that if there is a existing property then it can create a bean, however it is not working.

Can you suggest, please, one of your best practices for such case.


Solution

  • The way you should set properties for a test is to use the Spring Annotation @TestPropertySource

    You can either pass it a .properties file that contains the test properties, or declare your properties inline. i.e.

    @TestPropertySource(properties={"card.services.connection.baseUrl=http://localhost:8080"})
    

    An alternative (assuming you are using Spring Profiles) would be to setup application-test.properties with your test properties, and then annotate your @SpringBootTest class with the @ActiveProfiles annotation like the following so it can read the properties from application-test.properties

    @ActiveProfiles(value = "test")
    

    Edit:

    Based on comment from OP, ApplicationContextRunner is a valid solution as well. See also tutorial from Baeldung showing how to test property condition with ApplicationContextRunner