Reputation: 3660
I am using autowiring (@Autowired) to inject dependencies in JUnit test class and am facing NullPointerException. I would like to know if autowiring is possible with/in JUnit test class. Else how should beans be injected in test classes. My code is as below -
main class / client - autowiring works as expected.
package com.example.demo;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import com.example.demo.services.IMessage;
import com.example.demo.services.SayWelcomeService;
@SpringBootApplication
@ComponentScan("com.example.demo.services")
public class AutowireWithMultipleImplementationsApplication {
@Autowired
IMessage sayHelloService;
@Autowired
SayWelcomeService sayWelcome;
@Autowired
IMessage masterService;
public static void main(String[] args) {
SpringApplication.run(AutowireWithMultipleImplementationsApplication.class, args);
}
@PostConstruct
public void init() {
String message;
message=masterService.message("George");
System.out.println("message: \n" + message);
message=sayWelcome.message("george");
System.out.println("message: " + message);
}
}
Service interface and Implementation classes
interface IMessage
package com.example.demo.services;
public interface IMessage {
String message(String name);
}
Service SayWelcomeService
package com.example.demo.services;
import org.springframework.stereotype.Service;
@Service
public class SayWelcomeService implements IMessage {
@Override
public String message(String name) {
return "Welcome Dear User - " + name ;
}
}
service SayHelloService
package com.example.demo.services;
import org.springframework.stereotype.Service;
@Service
public class SayHelloService implements IMessage {
@Override
public String message(String name) {
return "Hello Dear User - " + name ;
}
}
master service calling other services. Autowiring works as expected.
MasterService
package com.example.demo.services;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class MasterService implements IMessage {
@Autowired
List<IMessage> listOfServices;
@Autowired
IMessage sayHelloService;
@Autowired
SayWelcomeService sayWelcome;
@Override
public String message(String name) {
StringBuilder messages = new StringBuilder();
for(IMessage m: listOfServices)
{
messages.append(m.message(name));
messages.append("\n");
}
System.out.println(".....");
System.out.println(sayHelloService.message(name));
System.out.println(sayWelcome.message(name));
return messages.toString();
}
}
Now the test class.
SayWelcomeServiceTest
package com.example.demo.tests;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import com.example.demo.services.SayWelcomeService;
public class SayWelcomeServiceTest {
@Autowired
SayWelcomeService sayWelcomeService;
@Test
public void testSayWelcomeMessage()
{
String message = sayWelcomeService.message("George");
assertThat(message, equalTo("Welcome Dear User - George"));
}
}
The problem is in the above class. @Autowired field(sayWelcomeService) is null. Why? How to solve this?
Upvotes: 2
Views: 13731
Reputation: 313
Seems like you are missing these annotations.
@SpringBootTest
@RunWith(SpringRunner.class)
Upvotes: 0
Reputation: 1564
Two more annotations were necessary to wire the bean. They are mandatory, otherwise the test will fail.
Here is the working test class:
@SpringBootTest
@RunWith(SpringRunner.class)
public class SayWelcomeServiceTest {
@Autowired
private SayWelcomeService sayWelcomeService;
@Test
public void testSayWelcomeMessage()
{
String message = sayWelcomeService.message("George");
assertThat(message, equalTo("Welcome Dear User - George"));
}
}
More information in Spring Boot Docs:
Spring Boot provides a @SpringBootTest annotation which can be used as an alternative to the standard spring-test @ContextConfiguration annotation when you need Spring Boot features. The annotation works by creating the ApplicationContext used in your tests via SpringApplication.
Upvotes: 6