New to Spring, I am building a toy application that represents a car dealership. Here's my interface for this service:
public interface DealershipService {
Long getRevenue();
void sell(Car car);
void buy(Car car);
List<Car> findByMake(String make);
List<Car> findByMakeAndModel(String make, String model);
List<Car> findByMakeModelAndYear(String make, String model, String year);
List<Car> findByYearRange(String yearLowInclusive, String yearHighInclusive);
List<Car> findInCostRange(long costLowInclusive, long costHighInclusive);
}
And here is a small part of the implementation (really all we need is the field revenue
).
@Slf4j
@Data
@Service
public class DealershipServiceImpl implements DealershipService {
@Value("${revenue}")
private Long revenue;
private final CarRepository carRepository;
@Autowired
public DealershipServiceImpl(CarRepository carRepository) {
this.carRepository = carRepository;
}
@Override
public void sell(Car car) {
carRepository.addToRepository(car);
revenue += car.getCostInUSD();
log.info("Sold car {}. Current revenue: {}", car, revenue);
}
.
.
.
The revenue
variable is in my application.properties
as:
revenue = 1000000
Because I want the default revenue for this car dealership to be 1000000 USD. Now I'm trying to write a test.
@SpringJUnitConfig(classes = TestConfig.class)
public class DealershipServiceIT {
@Autowired
private DealershipService dealershipService;
@Test
public void whenNoTransactions_TotalRevenueIsAMil(){
assertThat(dealershipService.getRevenue(), is(1_000_000L));
}
}
The TestConfig
class that the above unit test class points to:
@Configuration
@ComponentScan("com.jason.cardealership")
public class TestConfig {
}
My class' central @SpringBootApplication
class is this, and the context loads just fine when I run it:
@SpringBootApplication
public class CarDealershipApplication {
public static void main(String[] args) {
SpringApplication.run(CarDealershipApplication.class, args);
}
}
But when I run the test method whenNoTransactions_TotalRevenueIsAMil()
I get a sequence of exceptions, the bottom one of which is:
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'revenue' in value "${revenue}"
at org.springframework.util.PropertyPlaceholderHelper.parseStringValue(PropertyPlaceholderHelper.java:180)
at org.springframework.util.PropertyPlaceholderHelper.replacePlaceholders(PropertyPlaceholderHelper.java:126)
at org.springframework.core.env.AbstractPropertyResolver.doResolvePlaceholders(AbstractPropertyResolver.java:239)
at org.springframework.core.env.AbstractPropertyResolver.resolveRequiredPlaceholders(AbstractPropertyResolver.java:210)
at org.springframework.context.support.PropertySourcesPlaceholderConfigurer.lambda$processProperties$0(PropertySourcesPlaceholderConfigurer.java:191)
at org.springframework.beans.factory.support.AbstractBeanFactory.resolveEmbeddedValue(AbstractBeanFactory.java:920)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1346)
at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1325)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:709)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:692)
at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:133)
at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessProperties(AutowiredAnnotationBeanPostProcessor.java:481)
... 87 common frames omitted
I also added @PropertySource("classpath:application.properties")
on top of my testing class after consulting this post, but without success.
How can I read the value of that variable from within my test?