anon
anon

Reputation:

Using property values in JUnit test classes without load whole Spring Boot application context

I have a Spring Boot Component as below

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Slf4j
@Component
public class Client {

    @Value("${SecretKey}") private String secretKey;
    
    public void createAccount() {
        log.error("secretKey" + secretKey);
    }

}

How do I write a test class where Client class automatically use the resource/application.yaml in the test classpath, without loading the whole application context? I want to use like below :

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.junit.jupiter.SpringExtension;

@Slf4j
@ExtendWith(SpringExtension.class)
public class ClientTest {

    @Autowired
    private Client client;

    @DisplayName("Create Client")
    @Test
    public void givenX_thenCreateAccount() throws Exception {
       client.createAccount();
    }

}

The test class above throws :

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'com.payment.stripe.ClientTest': Unsatisfied dependency expressed through field 'client'; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'Client' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}

I don't want to load the whole application context just for secretKey thing because it is expensive.

I also don't want to create a constructor and manually give the key myself.

Upvotes: 2

Views: 1722

Answers (1)

Naresh J
Naresh J

Reputation: 2137

Main reason for this exception is without loading your class Client in springContext, you are trying to read it. So you are getting NoSuchBeanDefinitionException

You need to do 2 things.

  1. Load your class in context with class annotation @ContextConfiguration(classes = Client.class)
  2. Explicitly load you application.yaml from src folder as you are not having it in test/resource folder as @TestPropertySource(locations = "/application.yaml")

Upvotes: 2

Related Questions