최근 개발할 때, 직접 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을 허용하지 않도록 하면 됩니다.

 

잘 되네요!

 

 

 

반응형

+ Recent posts