3

I have updated SpringBoot version from 2.1.6 to 2.6.6 and after starting integration tests with testcontainers I am receiving below errors:

First error is:

13:25:08.793 [main] ERROR o.s.boot.SpringApplication - Application run failed
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'approvalResource': Unsatisfied dependency expressed through field 'queryApprovals'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'queryApprovals': Unsatisfied dependency expressed through field 'approvalRepository'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'approvalRepository' defined in adapters.outbound.repositories.ApprovalRepository defined in @EnableMongoRepositories declared on Licenses: Cannot create inner bean '(inner bean)#66589252' of type [org.springframework.data.repository.core.support.RepositoryFragmentsFactoryBean] while setting bean property 'repositoryFragments'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#66589252': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'squealRepositoryImplFragment': Cannot resolve reference to bean 'squealRepositoryImpl' while setting constructor argument; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'squealRepositoryImpl': Unsatisfied dependency expressed through field 'mongoTemplate'; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mongoTemplate' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryDependentConfiguration.class]: Unsatisfied dependency expressed through method 'mongoTemplate' parameter 0; nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mongoDatabaseFactory' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.class]: Unsatisfied dependency expressed through method 'mongoDatabaseFactory' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongo' defined in class path resource [org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mongodb.client.MongoClient]: Factory method 'mongo' threw exception; nested exception is java.lang.IllegalStateException: Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified

then:

Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mongoDatabaseFactory' defined in class path resource [org/springframework/boot/autoconfigure/data/mongo/MongoDatabaseFactoryConfiguration.class]: Unsatisfied dependency expressed through method 'mongoDatabaseFactory' parameter 0; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongo' defined in class path resource [org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mongodb.client.MongoClient]: Factory method 'mongo' threw exception; nested exception is java.lang.IllegalStateException: Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:800)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:541)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1389)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1309)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
    ... 169 common frames omitted
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'mongo' defined in class path resource [org/springframework/boot/autoconfigure/mongo/MongoAutoConfiguration.class]: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mongodb.client.MongoClient]: Factory method 'mongo' threw exception; nested exception is java.lang.IllegalStateException: Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:658)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:638)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1352)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1195)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:582)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1389)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1309)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:887)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
    ... 183 common frames omitted
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.mongodb.client.MongoClient]: Factory method 'mongo' threw exception; nested exception is java.lang.IllegalStateException: Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:185)
    at org.springframework.beans.factory.support.ConstructorResolver.instantiate(ConstructorResolver.java:653)
    ... 197 common frames omitted
Caused by: java.lang.IllegalStateException: Invalid mongo configuration, either uri or host/port/credentials/replicaSet must be specified
    at org.springframework.util.Assert.state(Assert.java:76)
    at org.springframework.boot.autoconfigure.mongo.MongoPropertiesClientSettingsBuilderCustomizer.validateConfiguration(MongoPropertiesClientSettingsBuilderCustomizer.java:61)
    at org.springframework.boot.autoconfigure.mongo.MongoPropertiesClientSettingsBuilderCustomizer.customize(MongoPropertiesClientSettingsBuilderCustomizer.java:52)
    at org.springframework.boot.autoconfigure.mongo.MongoClientFactorySupport.customize(MongoClientFactorySupport.java:55)
    at org.springframework.boot.autoconfigure.mongo.MongoClientFactorySupport.createMongoClient(MongoClientFactorySupport.java:49)
    at org.springframework.boot.autoconfigure.mongo.MongoAutoConfiguration.mongo(MongoAutoConfiguration.java:55)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.base/java.lang.reflect.Method.invoke(Method.java:566)
    at org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:154)
    ... 198 common frames omitted

Initializer class:

@Slf4j
public class IntegrationTestContextInitializer implements
        ApplicationContextInitializer<ConfigurableApplicationContext> {
    
    private static final MongoDBContainer mongoDbContainer = new MongoDBContainer(DockerImageName.parse("mongo:4.0.18-xenial")).withReuse(true);
    private static final KeycloakContainer keycloakContainer = new KeycloakContainer("jboss/keycloak:12.0.4")
                    .withRealmImportFile("test-realm.json")
                    .withAdminUsername("admin")
                    .withAdminPassword("password")
                    .withReuse(true)
                    .withStartupTimeout(Duration.ofMinutes(5));
    private static final GenericContainer<?> mailContainer = new GenericContainer<>(DockerImageName.parse("reachfive/fake-smtp-server:0.8.1")).withReuse(true).withExposedPorts(1025);

    static {
        mailContainer.start();
        mongoDbContainer.start();
        keycloakContainer.start();
    }

    @Override
    public void initialize(@NotNull ConfigurableApplicationContext configurableApplicationContext) {
        log.info("MongoDB URI: {}", mongoDbContainer.getReplicaSetUrl());
        log.info("Keycloak URI: {}", keycloakContainer.getAuthServerUrl());
        log.info("Mail server Port: {}", mailContainer.getMappedPort(1025));
        TestPropertyValues values = TestPropertyValues.of(
                "spring.data.mongodb.uri=" + mongoDbContainer.getReplicaSetUrl(),
                "de.easy.myeasy.licenses.keycloak.username=" + keycloakContainer.getAdminUsername(),
                "de.easy.myeasy.licenses.keycloak.password=" + keycloakContainer.getAdminPassword(),
                "keycloak.auth-server-url=" + keycloakContainer.getAuthServerUrl(),
                "spring.mail.host=" + mailContainer.getHost(),
                "spring.mail.port=" + mailContainer.getMappedPort(1025),
                "spring.mail.properties.mail.smtp.auth=false",
                "spring.mail.properties.mail.smtp.starttls.enable=false"
        );
        values.applyTo(configurableApplicationContext);
    }
}

BaseIT class:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
@AutoConfigureMockMvc
@ActiveProfiles("test")
@Slf4j
@ContextConfiguration(initializers = IntegrationTestContextInitializer.class)
public class BaseIntegrationTest {

    @Autowired
    protected ObjectMapper objectMapper;

    @Autowired
    protected MockMvc mockMvc;

    @Autowired
    protected MongoTemplate mongoTemplate;

    @Autowired
    protected WebApplicationContext webApplicationContext;

    @SuppressWarnings("unused")
    @Autowired
    private KeycloakService keycloakService;

    @Autowired
    private KeycloakUserAdminService keycloakUserAdminService;

    @Autowired
    private UserRepository userRepository;

    @Autowired
    private QueryProducts queryProducts;

    private final String[] downloadWhitelist = {"bit.ly", "downloads.com", "updatedlink.com", "newsownloadlink.com"};

    @BeforeEach
    public void setup() throws UserServiceException {
        log.info("--------- Integration Test Starting ---------");
        ReflectionTestUtils.setField(queryProducts, "downloadWhitelist", downloadWhitelist);        
        mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
        seedIntegrationTestUsers();
    }

    private void removeUser(String name){
        try{
            keycloakUserAdminService.deleteUser(name);
        } catch (UserServiceException e) {
            log.debug("Delete {} failed", name,e);
        }
    }

    @AfterEach
    public void tearDown() {
        Stream<String> collectionNames = mongoTemplate.getCollectionNames().stream().filter(cName -> !cName.startsWith("system"));
        collectionNames.forEach(cName -> mongoTemplate.findAllAndRemove(new Query(), cName));
        removeUser("it_tester@tester.com");
        removeUser("it_tester2@tester.com");
        removeUser("it_tester3@customera.com");
        log.info("--------- Integration Test Stopped ---------");
    }

    public void seedIntegrationTestUsers() throws UserServiceException {
        userRepository.save(User.builder().username("it_tester@tester.com").email("it_tester@tester.com").build());
        userRepository.save(User.builder().username("it_tester2@tester.com").email("it_tester2@tester.com").build());
        KeycloakUser keycloakUser = new KeycloakUser();
        keycloakUser.setUsername("it_tester@tester.com");
        keycloakUser.setEmail("it_tester@tester.com");
        keycloakUser.setFirstName("tester");
        keycloakUser.setLastName("tester");
        keycloakUser.setEnabled(true);
        KeycloakUser keycloakUser2 = new KeycloakUser();
        keycloakUser2.setUsername("it_tester2@tester.com");
        keycloakUser2.setEmail("it_tester2@tester.com");
        keycloakUser2.setFirstName("tester2");
        keycloakUser2.setLastName("tester2");
        keycloakUser2.setEnabled(true);
        KeycloakUser keycloakUser3 = new KeycloakUser();
        keycloakUser3.setUsername("it_tester3@customera.com");
        keycloakUser3.setEmail("it_tester3@customera.com");
        keycloakUser3.setFirstName("tester3");
        keycloakUser3.setLastName("tester3");
        keycloakUser3.setEnabled(true);
        keycloakUserAdminService.createUser(keycloakUser);
        keycloakUserAdminService.createUser(keycloakUser2);
        keycloakUserAdminService.createUser(keycloakUser3);
    }

}

Test class for loading context:

public class ContextLoadIntegrationTest extends BaseIntegrationTest{

    @Test
    void contextLoads() {
        System.out.println("Context loads!");
    }
}

Moreover I have @EnableMongoRepositories annotation in Application:

@SpringBootApplication
@EnableMongoRepositories(basePackages = {"adapters.outbound.repositories", "ps.squeal"})
public class MyApplication {

    public static void main(String[] args) throws NoSuchAlgorithmException, KeyManagementException {
        SpringApplication.run(MyApplication.class, args);
    }

}

It is working with Spring boot 2.1.6 but after migrating to 2.6.6 it is throwing errors. What is missing here to make it work? I am using JUnit5.

kemoT
  • 63
  • 8
  • try adding the following annotation in your IntegrationTest class `@NestedTestConfiguration(NestedTestConfiguration.EnclosingConfiguration.OVERRIDE)` If it works I can explain it more – Panagiotis Bougioukos Apr 14 '22 at 12:22
  • unfortunately this is not working, same error. – kemoT Apr 14 '22 at 12:42
  • 2
    You must be configuring some other `spring.data.mongodb.*` properties somewhere that you haven’t shown. They cannot be configured in combination with `spring.data.mongodb.uri`. – Andy Wilkinson Apr 14 '22 at 18:21
  • I have commented spring.data.mongodb.* on all properties files and it worked. Looks like it is not using profile test somehow. I will investigate it. Thank You for help :) – kemoT Apr 15 '22 at 08:09

1 Answers1

0

I have commented spring.data.mongodb.* in all properties files and it worked. Looks like Spring was not using test profile as stated in @ActiveProfiles("test") annotation.

kemoT
  • 63
  • 8