I have a configuration class that uses a properties file and it works properly.
Now I want to test that code and I have to recognize that the method annotated with @PostConstruct
is run twice during the test. (In debug mode I can see that the for-loop is conducted twice.)
The configuration class:
@Slf4j
@RequiredArgsConstructor
@Configuration
@ConfigurationPropertiesScan("com.foo.bar")
public class MyConfig {
private final MyProperties myProperties;
@Autowired
private GenericApplicationContext applicationContext;
@PostConstruct
void init() {
Objects.requireNonNull(myProperties, "myProperties may not be null");
for (final MyProperties.MyNestedProperty nested : myProperties.getApps()) {
log.info("xxx {} created.", nested.getName());
applicationContext.registerBean(nested.getName(), MyContributor.class, nested);
}
}
}
The used properties class:
@Slf4j
@Data
@Validated
@ConfigurationProperties(prefix = MyProperties.CONFIG_PREFIX)
public class MyProperties {
public static final String CONFIG_PREFIX = "xxx";
@Valid
@NestedConfigurationProperty
private List<MyNestedProperty> apps;
@Data
public static class MyNestedProperty {
@NotNull
@NotEmpty
private String abc;
private String xyzzy;
@NotNull
@NotEmpty
private String name;
}
}
My attempt with the test class:
@ExtendWith(SpringExtension.class)
@RequiredArgsConstructor
@ContextConfiguration(classes = MyConfigTest.MyTestConfiguration.class)
class MyConfigTest {
@MockBean
MyProperties myProperties;
ApplicationContextRunner context;
@BeforeEach
void init() {
context = new ApplicationContextRunner()
.withBean(MyProperties.class)
.withUserConfiguration(MyConfig.class)
;
}
@Test
void should_check_presence_of_myConfig() {
context.run(it -> {
assertThat(it).hasSingleBean(MyConfig.class);
});
}
// @Configuration
@SpringBootConfiguration
// @TestConfiguration
static class MyTestConfiguration {
@Bean
MyProperties myProperties() {
MyProperties myProperties = new MyProperties();
MyProperties.MyNestedProperty nested = new MyProperties.MyNestedProperty();
nested.setName("xxx");
nested.setAbc("abc");
nested.setXyz("xyz");
myProperties.setApps(List.of(nested));
return myProperties;
}
}
}
Why does this happen and how can I prevent this behaviour?