英文:
Spring Boot @Autowired in unit test returns NullPointerException
问题
I have a class(HttpHandler) annotated with @service. I'm writing unit test case for this service class.
我有一个使用 @service 注解的类(HttpHandler)。我正在为这个服务类编写单元测试用例。
I used @Autowired annotation in my test class to get the object of the service. However, When I run the unit test it return NullPointerException. Can someone help me?
我在我的测试类中使用了 @Autowired 注解来获取服务对象。然而,当我运行单元测试时,它返回了NullPointerException。有人能帮助我吗?
Below is the code of the service class:
以下是服务类的代码:
@Service
public class HttpHandler {
private static final Logger logger = LoggerFactory.getLogger(HttpHandler.class);
/**
* Build the request and Perform Http Get request with headers
* @param url
* @param httpHeaders
* @param responseClass
* @param <T>
* @param <R>
* @return
*/
public <T,R> ResponseEntity<T> sendPost(String url, HttpHeaders httpHeaders, R requestBody, Class<T> responseClass) {
//create an instance of rest template
RestTemplate restTemplate = new RestTemplate();
HttpEntity<R> entity = new HttpEntity<R>(requestBody, httpHeaders);
logger.info("POST request to " + url + " with body: " + JsonUtil.jsonizeExcludeNulls(requestBody));
//make an HTTP POST request with headers
ResponseEntity<T> response = restTemplate.exchange(url, HttpMethod.POST, entity, responseClass);
logger.info("POST" + url + ": " + JsonUtil.jsonize(response));
return response;
}
}
I'm writing unit test case for POST call. Below is the unit test for POST call
我正在编写POST调用的单元测试用例。以下是用于POST调用的单元测试:
public class HttpHandlerTest {
@Autowired
HttpHandler httpHandler;
@Test
public void testSuccessPostUser() throws Exception{
String baseUrl = "http://localhost:8080/users";
List<String> messages = new ArrayList<>();
messages.add("Hi");
User user = new User();
user.setId(1);
user.setName("John");
user.setAge(22);
user.setMessages(messages);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
HttpEntity<User> httpEntity = new HttpEntity<>(user, httpHeaders);
ResponseEntity<User> actual = httpHandler.sendPost(baseUrl, httpHeaders, user, User.class);
//verify request succeed
assertEquals(HttpStatus.CREATED, actual.getStatusCode());
assertEquals(201, actual.getStatusCodeValue());
assertTrue(actual.toString().contains("id"));
}
}
It gives below error:
它报以下错误:
java.lang.NullPointerException
at com.xyz.provisioning.xyz.utils.HttpHandlerTest.testSuccessPostUser(HttpHandlerTest.java:41)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
英文:
I have a class(HttpHandler) annotated with @service. I'm writing unit test case for this service class.
I used @Autowired annotation in my test class to get the object of the service. However, When I run the unit test it return NullPOinterException. Can someone help me?
Below is the code of service class:
@Service
public class HttpHandler {
private static final Logger logger = LoggerFactory.getLogger(HttpHandler.class);
/**
* Build the request and Perform Http Get request with headers
* @param url
* @param httpHeaders
* @param responseClass
* @param <T>
* @param <R>
* @return
*/
public <T,R> ResponseEntity<T> sendPost(String url, HttpHeaders httpHeaders, R requestBody, Class<T> responseClass) {
//create an instance of rest template
RestTemplate restTemplate = new RestTemplate();
HttpEntity<R> entity = new HttpEntity<R>(requestBody, httpHeaders);
logger.info("POST request to " + url + " with body: " + JsonUtil.jsonizeExcludeNulls(requestBody));
//make an HTTP POST request with headers
ResponseEntity<T> response = restTemplate.exchange(url, HttpMethod.POST, entity, responseClass);
logger.info("POST" + url + ": " + JsonUtil.jsonize(response));
return response;
}
}
I'm writing unit test case for POST call. Below is the unit test for POST call
public class HttpHandlerTest {
@Autowired
HttpHandler httpHandler;
@Test
public void testSuccessPostUser() throws Exception{
String baseUrl = "http://localhost:8080/users";
List<String> messages = new ArrayList<>();
messages.add("Hi");
User user = new User();
user.setId(1);
user.setName("John");
user.setAge(22);
user.setMessages(messages);
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
httpHeaders.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON));
HttpEntity<User> httpEntity = new HttpEntity<>(user, httpHeaders);
ResponseEntity<User> actual = httpHandler.sendPost(baseUrl, httpHeaders, user, User.class);
//verify request succeed
assertEquals(HttpStatus.CREATED, actual.getStatusCode());
assertEquals(201, actual.getStatusCodeValue());
assertTrue(actual.toString().contains("id"));
}
}
It gives below error:
java.lang.NullPointerException
at com.xyz.provisioning.xyz.utils.HttpHandlerTest.testSuccessPostUser(HttpHandlerTest.java:41)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.platform.commons.util.ReflectionUtils.invokeMethod(ReflectionUtils.java:686)
at org.junit.jupiter.engine.execution.MethodInvocation.proceed(MethodInvocation.java:60)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$ValidatingInvocation.proceed(InvocationInterceptorChain.java:131)
at org.junit.jupiter.engine.extension.TimeoutExtension.intercept(TimeoutExtension.java:149)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestableMethod(TimeoutExtension.java:140)
at org.junit.jupiter.engine.extension.TimeoutExtension.interceptTestMethod(TimeoutExtension.java:84)
at org.junit.jupiter.engine.execution.ExecutableInvoker$ReflectiveInterceptorCall.lambda$ofVoidMethod$0(ExecutableInvoker.java:115)
at org.junit.jupiter.engine.execution.ExecutableInvoker.lambda$invoke$0(ExecutableInvoker.java:105)
at org.junit.jupiter.engine.execution.InvocationInterceptorChain$InterceptedInvocation.proceed(InvocationInterceptorChain.java:106)
答案1
得分: 3
对于JUnit 5(如评论中所提到的),您只需在测试类的顶部添加`@SpringBootTest`注解。
```java
@SpringBootTest
class HttpHandlerTest{
// ...
}
不需要添加@ExtendWith(SpringExtension.class)
,因为它会被@SpringBootTest
注解自动导入。
要在JUnit 4中获得相同的结果:
@RunWith(SpringRunner.class)
@SpringBootTest
class HttpHandlerTest{
// ...
}
<details>
<summary>英文:</summary>
For Junit 5 (as mentioned in the comments) you just need to add `@SpringBootTest` on top of the test class.
```java
@SpringBootTest
class HttpHandlerTest{
// ...
}
You don't need to add @ExtendWith(SpringExtension.class)
because is automatically imported by the annotation @SpringBootTest
.
To get the same result for Junit 4:
@RunWith(SpringRunner.class)
@SpringBootTest
class HttpHandlerTest{
// ...
}
答案2
得分: 2
在类上面添加@ExtendWith(SpringExtension.class)
,如果你使用JUnit5,或者添加@RunWith(SpringRunner.class)
,如果你使用JUnit4。
英文:
Add @ExtendWith(SpringExtension.class)
above the class if you're using JUnit5 or @RunWith(SpringRunner.class)
if you're using JUnit4.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论