56

I'm quite a newbie to Spring boot, but here's the problem I'm facing now:

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

  @Autowired
  private Cluster cluster = null;

  @PostConstruct
  private void migrateCassandra() {
    Database database = new Database(this.cluster, "foo");
    MigrationTask migration = new MigrationTask(database, new MigrationRepository());
    migration.migrate();
  }
}

So basically, I'm trying to bootstrap a spring application, and after that, do some cassandra migrations.

I also have defined a repository for my user model:

// UserRepo.java
public interface UserRepo extends CassandraRepository<User> {
}

Now I'm trying to test my repo class using the following simple test case:

// UserRepoTest.java
@RunWith(SpringRunner.class)
@AutoConfigureTestDatabase(replace = Replace.NONE)
@DataJpaTest
public class UserRepoTest {

  @Autowired
  private UserRepo userRepo = null;

  @Autowired
  private TestEntityManager entityManager = null;

  @Test
  public void findOne_whenUserExists_thenReturnUser() {
    String id = UUID.randomUUID().toString();
    User user = new User();
    user.setId(id);
    this.entityManager.persist(user);

    assertEquals(this.userRepo.findOne(user.getId()).getId(), id);
  }

  @Test
  public void findOne_whenUserNotExists_thenReturnNull() {
    assertNull(this.userRepo.findOne(UUID.randomUUID().toString()));
  }
}

I would expect the test to pass, but instead, I got an error saying "No qualifying bean of type 'com.datastax.driver.core.Cluster' available". It looks like spring failed to autowire the cluster object, but why is that? How do I fix this? Thanks a lot!

fengye87
  • 2,433
  • 4
  • 24
  • 41
  • Where you see a bean of class cluster (implementation of an Interface Cluster) in your code that can be autovired?? – Jens Jul 05 '17 at 11:48
  • 1
    one possible Solution: remove this two lines: `@Autowired private Cluster cluster = null;` – Jens Jul 05 '17 at 11:49
  • I haven't defined any bean of Class Cluster, it's supposed to be provided by spring-boot-starter-data-cassandra. And if I run my application, it just works. – fengye87 Jul 05 '17 at 11:50
  • then there is something in the testconfiguration missing – Jens Jul 05 '17 at 11:52

1 Answers1

94

The test environment needs to know where your beans are defined, so you have to tell it the location.

In your test class, add the @ContextConfiguration annotation:

@RunWith(SpringRunner.class)
@AutoConfigureTestDatabase(replace = Replace.NONE)
@DataJpaTest
@ContextConfiguration(classes = {YourBeans.class, MoreOfYourBeans.class})
public class UserRepoTest {

  @Autowired
  private UserRepo userRepo = null;

  @Autowired
  private TestEntityManager entityManager = null;
JimHawkins
  • 4,843
  • 8
  • 35
  • 55
  • 3
    I was hoping the cluster instance will get autowired like it does in application bootstraping. What's the difference for the test environment? – fengye87 Jul 05 '17 at 12:03
  • 1
    AFAIK, the class `Applcation` where you call `SpringApplication.run(Application.class, args)` isn't used when your tests are executed – JimHawkins Jul 05 '17 at 12:40
  • 2
    Jim's statement is correct. In the Spring Boot app, you have a configuration class which is supplying `Cluster`. You need (and should have) a separate config class or XML for unit tests to create any beans you need. Also, `@Autowired private UserRepo userRepo = null;` is redundant. These are null by default. And you should try to use [constructor injection](https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-spring-beans-and-dependency-injection.html) to make testing easier. – Christopher Schneider Jul 05 '17 at 13:06
  • 3
    Is you are creating a spring-boot application with spring-boot-test since 1.4, you can annotate your test classes with `@SpringBootTest`. – AndreFontaine Mar 27 '18 at 12:21
  • Instead @ContextConfiguration can't we provide basePackage? – NK_Mimrot Aug 04 '20 at 11:35
  • Unable to retrieve @EnableAutoConfiguration base packages. Any ideas? – kylie.zoltan Aug 19 '22 at 10:56
  • Thank you so much, I always only found something about using the ContextConfiguration in combination with some files and this finally solved my problems after a long time, thanks so much! – Gabriel Aug 27 '23 at 19:00