본문 바로가기
스프링부트와 AWS

#3-2_스프링부트에서 테스트코드 작성 +java.lang.NullPointerException 에러 해결방법

by Meaning_ 2021. 7. 23.
728x90
반응형

java.lang.NullPointerException 에러를 찾으시는 분들은 스크롤을 아래로 내리시면 됩니다.(중간에 삽질한걸 기록해놔서 서두가 길어요 하하)

 

#3-1내용은

https://we1cometomeanings.tistory.com/64

 

#3-1_스프링부트에서 테스트 코드를 작성 + 인텔리제이 테스트 코드 작성시 cannot resolve symbol 에러

TDD와 단위테스트 TDD는 테스트가 주도하는 개발 -> 테스트코드를 먼저 작성하는 것에서부터 시작 - 항상 실패하는 테스트를 먼저 작성 - 테스트가 통과하는 프로덕션 코드 작성 - 테스트가 통과하

we1cometomeanings.tistory.com

 

 

 

HelloControllerTest를 롬복으로 전환하기


 

앞으로 모든 응답 Dto는 이 Dto패키지에 추가해줄 것이다.

 

main ->java-.web에 dto패키지를 추가시켜준다

 

HelloResponseDto 클래스를 만들고,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
 
import org.springframework.web.bind.annotation.GetMapping;
 
import org.springframework.web.bind.annotation.RestController;
 
@RestController
public class HelloController {
    @GetMapping("/hello")
    public String hello() {
        return "hello";
    }
    
 
 
}
cs

 

이렇게 써준다.

 

main->test->web하위에 dto 폴더 만들고 HelloResponseDtoTest라는 클래스를 만들어준다.(Dto에 적용된 롬복이 잘 돌아가는지 확인하기 위함)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
 
import org.testng.annotations.Test;
 
import static org.assertj.core.api.Assertions.assertThat;
 
@Test
public class HelloResponseDtoTest {
    public void 롬복_기능_테스트(){
        //given
        String name="test";
        int amount=1000;
 
        //when
        HelloResponseDto dto=new HelloResponseDto(name,amount);
 
        //then
        assertThat(dto.getName()).isEqualTo(name);
        assertThat(dto.getAmount()).isEqualTo(amount);
    }
}
cs

 

 

 

롬복으로 변환한 HelloResponseDtoTest는 실행될줄 알았지만, 

 

java.lang.illegalaccesserror: class lombok.javac.apt.lombokprocessor 에러메세지 때문에 테스트코드가 실행되지 않았다.

 

 

 

테스트 코드가 실행이 안될 때 방법1 - gradle 다운그레이드 시켜주기

작가님이 qr코드로 올려주신 깃허브 이슈를 봤었는데, 거기서는 해결방법이

https://github.com/jojoldu/freelec-springboot2-webservice/issues/2

 

P74 테스트코드에서 에러가 발생합니다. · Issue #2 · jojoldu/freelec-springboot2-webservice

HelloResponseDtoTest.java에서 메소드 실행 시 아래와 같은 에러가 발생합니다. Testing started at 오후 11:08 ... Task :cleanTest UP-TO-DATE Task :compileJava FAILED C:\Users\ssooy\Desktop\dev\springboot-book\src\main\java\c...

github.com

gradlew wrapper --gradle-version 4.10.2

터미널창에 위코드를 입력해서 gradle 버전을 다운 그레이드 시켜주는 것이였다.

 

하지만

 

이렇게 다운 그레이드 시켜줘도 결국 gradle sync가 안맞아서 실패...ㅜ

다시 원래 버전이였던 gradle 7.0으로 gradle wrapper 파일에 수정해줬다.

 

버전확인 방법은 터미널 열고

 

gradlew -v

위에 코드 입력해주면 된다!


테스트 코드가 실행이 안될 때 방법 2- 롬복 1.18.20으로 맞춰주고, @AutoConfigureMockMvc 어노테이션으로 바꿔주기 

 

 

 

그래서  build.gradle 을 다시 설정해봤다.

https://projectlombok.org/setup/gradle

 

Gradle

 

projectlombok.org

위 사이트에서 하라는대로 했다.

 

빨간펜 처리한 부분만큼 다시 설정하고 

 

 

 test->dto 디렉토리에 HelloResponseDto 클래스에서 롬복기능테스트 메서드를 build하니 테스트를 통과했다!

 

테스트코드를 수동을 실행해보면

main->java->application 클래스에서 빨간 동그라미를 클릭하니 

 

 

톰캣 서버가 8080포트로 실행되었다는 것도 로그에 출력된다.

 

localhost:8080/hello 를 url에 써보니 hello가 나오는 것을 알 수 있다!

 

<오류와 관련해서 참고한 stackoverflow>

https://stackoverflow.com/questions/66801256/java-lang-illegalaccesserror-class-lombok-javac-apt-lombokprocessor-cannot-acce

 

java.lang.IllegalAccessError: class lombok.javac.apt.LombokProcessor cannot access class com.sun.tools.javac.processing.JavacPro

I am somewhat new to coding and am trying to use the Lombok plugin to automatically create Getters/Setters e.t.c. for my fields of a specific class. In doing so I get greeted with the following err...

stackoverflow.com

 


하지만 여전히 HelloControllerTest는 

 

널포인터 에러때문에 테스트코드가 돌아가지 않는다 ㅋㅋㅋㅋ(진짜 미친거 아닐까 ㅋㅋㅋㅋ)

이유는 this.mvc가 null이라고 한다

 

 

https://www.kejisen.com/ko/article/197897560.html

 

Spring Boot MVC 테스트-MockMvc는 항상 null입니다. - Kejisen

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오. 침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

www.kejisen.com

 

https://stackoverflow.com/questions/59534247/spring-boot-mvc-test-mockmvc-is-always-null

 

Spring Boot MVC Test - MockMvc is always null

I'm trying to write my first Spring MVC test but I just cannot get Spring Boot to inject the MockMvc dependency into my test class. Here is my class: @WebMvcTest public class WhyWontThisWorkTest {...

stackoverflow.com

위의 두 링크에 의하면

 

 @WebMvcTest 주석이 달린 테스트는 Spring Security 및 MockMvc도 자동 구성하는데, MockMVC를보다 세밀하게 제어하려면 @AutoConfigureMockMvc 주석을 사용할 수 있다. 두 주석의 차이점은 아래 링크에 설명해두었다.

 

https://we1cometomeanings.tistory.com/65

 

#3-3_ 스프링부트 테스트코드 작성시 @WebMvcTest 와 @AutoConfigureMockMvc 의 차이점

 

we1cometomeanings.tistory.com

     

 

이곳을 참고해서 HelloControllerTest의 코드를 책과 달리 수정해봤다!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import org.junit.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
 
import org.springframework.boot.test.autoconfigure.web.servlet.AutoConfigureMockMvc;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit.jupiter.SpringExtension;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
 
import static org.hamcrest.Matchers.is;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
 
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
 
 
public class HelloControllerTest {
    @Autowired
    private MockMvc mockMvc;
 
 
 
 
    @Test
    public void hello_return()throws Exception{
        String hello="hello";
        mockMvc.perform(get("/hello"))
 
                .andExpect(status().isOk())
                .andExpect(content().string(hello));
 
    }
 
    
}
cs

 

 

 @SpringBootTest(webEnvironment=WebEnvironment.MOCK) 설정으로 모킹한 객체를 의존성 주입받으려면 @AutoCOnfigureMockMvc를 클래스 위에 추가 해야한다. 그래서 보통

@RunWith(SpringRunner.class)

@SpringBootTest

@AutoConfigureMockMvc

 

세개의 어노테이션을 같이 쓰는 것 같다. 

 

 

 

HelloControllerTest도 실행이 완료되었다!!!!!!!!

 

 

Junit 5을 사용하는 사람들은

https://jojoldu.tistory.com/539

 

(2020.12.16) 스프링 부트와 AWS로 혼자 구현하는 웹 서비스 최신 코드로 변경하기

작년 11월 말에 스프링 부트와 AWS로 혼자 구현하는 웹 서비스를 출판 하였습니다. Spring Boot가 2.1 -> 2.4로, IntelliJ IDEA가 2019 -> 2020으로 오면서 너무 많은 변화가 있다보니, 집필할 때와 비교해 실습

jojoldu.tistory.com

 

링크를 참고해서 annotation들을 바꿔야 테스트할때 깨지지 않는다.

 

나는 JUnit4를 사용하고 있었는데 그것도 모르고 5버전으로 annotation을 바꿔서 계속 에러가 떴었다.

특히 JUnit 4를 사용할 때 주석은 @RunWith (SpringRunner.class)와 함께 사용해야한다!


HelloController 에도 새로만든 ResponseDto 를 사용하도록 코드를 추가해보겠다.

 

 

빨간펜 만큼을 추가하면된다

 

여기서  name과 amount는 API를 호출하는 곳에서 넘겨준 값들인데 추가된 API를 테스트하는 코드를 HelloControllerTest에 추가한다.

 

JSON이 리턴되는 API 역시 정상적으로 테스트 통과하는 것을 알 수 있다

728x90
반응형

댓글