최근 개발할 때, 직접 postman으로 테스트 하는 것보다는 테스트 코드를 작성해서 돌려봅니다.
간단하게 테스트해볼 것이 있어서 통합테스트를 했었는데, 계속 null pointer exception이 발생했었습니다.
이 부분이 문제되는 코드 입니다.
@Service
public class SimpleService {
public Integer add(Integer a, Integer b) {
return a+ b;
}
}
@RestController
@RequiredArgsConstructor
public class SimpleController {
private SimpleService simpleService;
@RequestMapping("/")
public Map<String, Integer> add(Integer a, Integer b) {
Map<String, Integer> response = new HashMap<>();
response.put("ret", simpleService.add(a,b));
return response;
}
}
이 코드를 가지고 아래와 같이 테스트를 해보겠습니다.
@SpringBootTest
@AutoConfigureMockMvc
class DemoApplicationTests {
@Autowired
private MockMvc mockMvc;
@Test
void contextLoads() throws Exception {
MultiValueMap<String, String> req = new LinkedMultiValueMap<>();
req.add("a", "1");
req.add("b", "2");
mockMvc.perform(MockMvcRequestBuilders.get("/").params(req))
.andExpect(MockMvcResultMatchers.jsonPath("$.ret").value(3));
}
}
이 때, null pointer exception이 발생합니다.
SimpleService.add(...)에서 발생한 것을 알 수 있습니다. 이 부분에 bean이 주입이 되지 않아서 이러한 에러가 발생합니다.
이를 해결하려면 매우 간단합니다.
@Service
public class SimpleService {
public Integer add(Integer a, Integer b) {
return a+ b;
}
}
@RestController
@RequiredArgsConstructor
public class SimpleController {
//private SimpleService simpleService;
private final SimpleService simpleService; //버그 수정
@RequestMapping("/")
public Map<String, Integer> add(Integer a, Integer b) {
Map<String, Integer> response = new HashMap<>();
response.put("ret", simpleService.add(a,b));
return response;
}
}
이렇게 final만 붙이면 됩니다.
왜 이러한 에러가 발생했을까요?
lombok의 @RequiredArgsConstructor 때문입니다.
이 코드의 docs를 보면,
이런 식으로 final fields가 필요하다는 것을 알 수 있습니다. 아니면 @NonNull 같은 null을 허용하지 않도록 하면 됩니다.
잘 되네요!
반응형
'BackEnd > spring' 카테고리의 다른 글
[Spring] @Value @SpringBootTest 없이 테스트하는 법 (0) | 2024.02.28 |
---|---|
[Spring] AOP 테스트 (2) | 2023.12.21 |
[인프런] 스프링 핵심 원리 고급편(김영한) 정리 (0) | 2023.07.30 |
[인프런] 스프링 핵심원리 기본편(김영한) 정리 (0) | 2023.07.28 |
[Spring] XSS 방지 (0) | 2023.05.26 |