Home > Back-end >  JUnit not Initializing Services Parameters
JUnit not Initializing Services Parameters

Time:11-22

I have a SpringBoot application, basically with a structure similar to the following:

application:

@SpringBootApplication
public class MyApplication {

@Autowired
MainService mainService;

    public static void main(String[] args) {

            SpringApplication.run(MyApplication.class, args);
    }


    @KafkaListener(topics = "myTopic")
    public void listen(String message) {

        this.graphicService.performWork();

     }
}

first service:

@Service
public MainService {

@Autowired MyService myService;

    public performWork() {

       this.myService.doStuff();
    }
}

second service:

@Service
public class MyService {

// server.param1 and server.param2 are defined in application.properties file
@Value("${server.param1}")
private String param1;
@Value("${server.param2}")
private String param2;

@PostConstruct
public void initService(){
}
    public void doStuff() {
        // do stuff assuming the parameters param1 and param 2 of this autowired service have already been initialized
   }
}

I have a junit like the following:

@SpringBootTest(classes = MyApplication.class)
class MyServiceTest {

    @Test
    void testMyService() {

        MyService myService = new MyService();

        myService.doStuff();
    }
}

When I execute testMyService, I get an exception thrown, essentially like this:

java.lang.IllegalStateException: Failed to load ApplicationContext
.
.
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'myApplication': Unsatisfied dependency expressed through field 'mainService';
.
.
Caused by: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'mainService': Unsatisfied dependency expressed through field 'myService'
.
.
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'myService': Injection of autowired dependencies failed
.
.
Caused by: java.lang.IllegalArgumentException: Could not resolve placeholder 'server.param1' in value "${server.param1}"

The application works fine operationally. I thought that the way I set up the junit, the springboot app would simply fire up and the parameters found in the application.properties file would simply be available to MyService service as are they when I run the application itself (not the junit).

Obviously I am doing something wrong, and the application context is not available the way I have this junit set up. I would be grateful for any ideas for getting this to work properly.

Thanks!

CodePudding user response:

Wire your class under test in the Junit test like in any production code class.

The @SpringBootTest will autodetect the @SpringBootApplication, so no extra parameter is needed. Just wire the needed dependencies like you would in the application classes.

The test will use the src/test/resources/application.properties (or yml) file, if present. If not present, the src/main/resources/application.properties is used. So if you use environment variables in your production application.yml copy this file to the test resources and fill the parameters with dummy parameters for test.

@SpringBootTest
class MyServiceTest {

    @Autowired MyService myService;

    @Test
    void testMyService() {

        myService.doStuff();
    }
}

If you like you can add the parameters in the test class with @TestPropertySource(properties

@SpringBootTest
@TestPropertySource(properties = {
    "server.param1=srv1",
    "server.param2=srv2"
})
class MyServiceTest {
...

Make sure you have spring-boot-starter-test in your dependencies.

Maven Example:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-test</artifactId>
    <version>2.7.5</version>
    <scope>test</scope>
</dependency>
  • Related