I am trying to write a unit test case to test the method, but I encounter a problem.
here is the sample code:
MyService1
@Service
public class MyService1 {
@Autowired
private ServiceProperties serviceProperties;
public void getMyLanguage(){
String language = serviceProperties.getLocale().getLanguage();
printSomething(language);
}
private void printSomething(String input){
System.out.print("your current language is " + input);
}
}
ServiceProperties
import org.springframework.boot.context.properties.ConfigurationProperties;
import java.util.Locale;
@ConfigurationProperties(prefix = "conversation")
public class ServiceProperties {
private ServiceProperties(){};
private Locale locale;
public Locale getLocale(){
return locale;
}
}
application.properties
conversation.locale=en_US
Here is my test case:
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.junit.MockitoJUnitRunner;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
@RunWith(MockitoJUnitRunner.class)
public class MyService1Test {
@Mock
private ServiceProperties serviceProperties;
@InjectMocks
private MyService1 myService1;
@Test
public void getMyLanguage(){
when(serviceProperties.getLocale().getLanguage()).thenReturn("EN");
myService1.getMyLanguage();
verify(myService1).getMyLanguage();
}
}
the test will trigger nullpointerexception, because the properties for locale are not loaded in test, if I don't want to start the server(use @SpringBootTest annotation) to load the context, is there any way to solve this problem, can anyone help?
The problem is at this line:
when(serviceProperties.getLocale().getLanguage()).thenReturn("EN");
Because serviceProperties
is mocked, serviceProperties.getLocale()
is equal to null
. So you get NullPointerException
when serviceProperties.getLocale().getLanguage()
is called.
One workaround would be as follows:
@RunWith(MockitoJUnitRunner.class)
public class MyService1Test {
@Mock
private ServiceProperties serviceProperties;
@InjectMocks
private MyService1 myService1;
@Test
public void getMyLanguage(){
when(serviceProperties.getLocale()).thenReturn(new Locale("EN"));
myService1.getMyLanguage();
verify(myService1).getMyLanguage();
}
}
Field injection is not convenient for testing. You can use constructor injection
@Service
public class MyService {
private final ServiceProperties serviceProperties;
@Autowired
public MyService(ServiceProperties serviceProperties) {
this.serviceProperties = serviceProperties;
}
//...
}
And then you will be able to inject mocks before each test
@RunWith(MockitoJUnitRunner.class)
public class MyService1Test {
@Mock
private ServiceProperties serviceProperties;
private MyService1 myService1;
@Before
public void createService(){
myService1 = new MyService1(serviceProperties);
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.