Issue
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.
Solution
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.
- Load your class in context with class annotation
@ContextConfiguration(classes = Client.class)
- Explicitly load you
application.yaml
from src folder as you are not having it in test/resource folder as@TestPropertySource(locations = "/application.yaml")
Answered By - Naresh J