[Exception ์ •๋ฆฌ] Spring Security PasswordEncoder Test NPE(Null Pointer Exception)

2022. 1. 26. 20:07ใ†๊ฐœ๋… ์ •๋ฆฌ ์ž‘์—…์‹ค/๋ฌธ์ œ ์ •๋ฆฌ

728x90
๋ฐ˜์‘ํ˜•

๐Ÿš€ Code Content

 

Spring Security๋ฅผ ์‚ฌ์šฉํ•ด์„œ ํšŒ์›๊ฐ€์ž…, ๋กœ๊ทธ์ธ ๋“ฑ์„ ์ฒ˜๋ฆฌํ•˜๋ ค๊ณ  ํ•˜๋Š” ๊ฒƒ์ด์—์š”.

๋จผ์ € ํšŒ์›์ด ์ž˜ ๋งŒ๋“ค์–ด์ง€๋Š”์ง€ Test๋ฅผ ํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์•„๋ž˜์™€ ๊ฐ™์ด Test Code๋ฅผ ์ž‘์„ฑํ•œ ๊ฒƒ์ด์—์š”.

 

package com.hongga.repository;

import com.hongga.entity.Member;
import com.hongga.entity.MemberRole;
import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.password.PasswordEncoder;

import java.util.stream.IntStream;

/**
 * ํšŒ์› ๊ด€๋ฆฌ Test Code
 * <pre>
 * <b>History:</b>
 *    ์ฃผ๋‹ˆํ•˜๋ž‘, 1.0, 2022.01.26 ์ตœ์ดˆ ์ž‘์„ฑ
 * </pre>
 *
 * @author ์ฃผ๋‹ˆํ•˜๋ž‘
 * @version 1.0, 2022.01.26 ์ตœ์ดˆ ์ž‘์„ฑ
 * @See "์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ ์›น ํ”„๋กœ์ ํŠธ"
 * @see <a href=""></a>
 */

@SpringBootTest
public class MemberRepositoryTest {

    @Autowired private MemberRepository repository;

    @Autowired private PasswordEncoder passwordEncoder;

    @Test public void ํ…Œ์ŠคํŠธ์šฉ_ํšŒ์›_์ƒ์„ฑ() {
        // 1๋ช…๋งŒ Admin ์ง€์ •
        // 2 ~ 90 ๊นŒ์ง€ Guest ์ง€์ •
        // 91 ~ 100 ๊นŒ์ง€ Family ์ง€์ •

        String rowPwd = "1111";

        IntStream.rangeClosed(1, 100).forEach(memberRoleCnt -> {
            Member member = Member.builder()
                    .email("hongga"+memberRoleCnt+"@hongga.com")
                    .name("ํ…Œ์ŠคํŠธ ์ด์šฉ์ž"+memberRoleCnt)
                    .nickName("ํ…Œ์ŠคํŠธ ์ด์šฉ์ž"+memberRoleCnt)
                    .password(passwordEncoder.encode(rowPwd))
                    .aboutMe("์•ˆ๋…•ํ•˜์„ธ์š”? ์šฐ๋ฆฌ ๊ฐ€์กฑ์—๊ฒŒ ์–ธ์ œ๋‚˜ ํ–‰๋ณต์ด ๊ฐ€๋“ํ•˜๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค!"+memberRoleCnt)
                    .build();

            // Admin ์—ญํ• 
            if (memberRoleCnt == 1) {
                member.addMemberRole(MemberRole.ADMIN);
            } // if๋ฌธ ๋

            if (memberRoleCnt > 90) {
                member.addMemberRole(MemberRole.GUEST);
            } // if๋ฌธ ๋

            if (memberRoleCnt >= 100) {
                member.addMemberRole(MemberRole.FAMILY);
            }

            repository.save(member);
        });
    } // ํ…Œ์ŠคํŠธ์šฉ_ํšŒ์›_์ƒ์„ฑ() ๋

} // class ๋

โš ๏ธ ๋ฌธ์ œ ๋ฐœ์ƒ!

 

์œ„์˜ Test Code๋ฅผ ์‹คํ–‰ํ•˜๋‹ˆ ๋‹ค์Œ๊ณผ ๊ฐ™์ด Null Pointer Exception์ด ๋ฐœ์ƒํ•œ ๊ฒƒ์ด์—์š”!

๋นŒ๋“œ ํŒจํ„ด์œผ๋กœ .password์— ๋ถ„๋ช…ํžˆ ๊ฐ’์„ ์ง‘์–ด๋„ฃ์–ด ์คฌ๋Š”๋ฐ, ์™œ? ๋•Œ๋ฌธ์—? ์ด๋Ÿฌ๋Š”์ง€ ์ „ํ˜€ ๋ชจ๋ฅด๊ฒ ๋Š”๋ฐ, ๋“œ๋””์–ด ๋‹ต์„ ์•Œ์•˜๋‹ต๋‹ˆ๋‹ค!

 

๐Ÿป ๋ฌธ์ œ ํ•ด๊ฒฐ!

 

package com.hongga.repository;

import com.hongga.entity.Member;
import com.hongga.entity.MemberRole;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.test.context.junit4.SpringRunner;

import java.util.stream.IntStream;

/**
 * ํšŒ์› ๊ด€๋ฆฌ Test Code
 * <pre>
 * <b>History:</b>
 *    ์ฃผ๋‹ˆํ•˜๋ž‘, 1.0, 2022.01.26 ์ตœ์ดˆ ์ž‘์„ฑ
 * </pre>
 *
 * @author ์ฃผ๋‹ˆํ•˜๋ž‘
 * @version 1.0, 2022.01.26 ์ตœ์ดˆ ์ž‘์„ฑ
 * @See "์ฝ”๋“œ๋กœ ๋ฐฐ์šฐ๋Š” ์Šคํ”„๋ง ๋ถ€ํŠธ ์›น ํ”„๋กœ์ ํŠธ"
 * @see <a href=""></a>
 */

@SpringBootTest @RunWith(SpringRunner.class)
public class MemberRepositoryTest {

    @Autowired private MemberRepository repository;

    @Autowired private PasswordEncoder passwordEncoder;

    @Test public void ํ…Œ์ŠคํŠธ์šฉ_ํšŒ์›_์ƒ์„ฑ() {
        // 1๋ช…๋งŒ Admin ์ง€์ •
        // 2 ~ 90 ๊นŒ์ง€ Guest ์ง€์ •
        // 91 ~ 100 ๊นŒ์ง€ Family ์ง€์ •

        String rowPwd = "1111";

        IntStream.rangeClosed(1, 100).forEach(memberRoleCnt -> {
            Member member = Member.builder()
                    .email("hongga"+memberRoleCnt+"@hongga.com")
                    .name("ํ…Œ์ŠคํŠธ ์ด์šฉ์ž"+memberRoleCnt)
                    .nickName("ํ…Œ์ŠคํŠธ ์ด์šฉ์ž"+memberRoleCnt)
                    .password(passwordEncoder.encode(rowPwd))
                    .aboutMe("์•ˆ๋…•ํ•˜์„ธ์š”? ์šฐ๋ฆฌ ๊ฐ€์กฑ์—๊ฒŒ ์–ธ์ œ๋‚˜ ํ–‰๋ณต์ด ๊ฐ€๋“ํ•˜๊ธธ ๋ฐ”๋ž๋‹ˆ๋‹ค!"+memberRoleCnt)
                    .build();

            // Admin ์—ญํ• 
            if (memberRoleCnt == 1) {
                member.addMemberRole(MemberRole.ADMIN);
            } // if๋ฌธ ๋

            if (memberRoleCnt > 90) {
                member.addMemberRole(MemberRole.GUEST);
            } // if๋ฌธ ๋

            if (memberRoleCnt >= 100) {
                member.addMemberRole(MemberRole.FAMILY);
            }

            repository.save(member);
        });
    } // ํ…Œ์ŠคํŠธ์šฉ_ํšŒ์›_์ƒ์„ฑ() ๋

} // class ๋

Class ์ด๋ฆ„ ์œ„์— ๋ณด์‹œ๋ฉด @RunWith๋ผ๋Š” Annotaion์ด ์ถ”๊ฐ€ ๋œ ๊ฒƒ์„ ์•„์‹ค ์ˆ˜ ์žˆ์œผ์‹ค ๊ฒƒ์ด์—์š”.

 

     ๐Ÿ”ฝ  ๋‹ค๋ฅธ ํ•ด๊ฒฐ ๋ฐฉ๋ฒ•

 

์œ„์—์„œ ์›๋ž˜ ์ฝ”๋“œ์— Import๋ฅผ ๋ณด์‹œ๋ฉด Test๋ถ€๋ถ„์ด 'org.junit.Test'๋กœ ๋˜์–ด ์žˆ๋Š”๋ฐ, ์ด ๋ถ€๋ถ„์„ 'org.junit.jupiter.api.Test"๋กœ ๋ฐ”๊ฟ”์ฃผ๋ฉด @RunWith๋ฅผ ๋ถ™ํžˆ์ง€ ์•Š์•„๋„ ๋ฌธ์ œ๊ฐ€ ํ•ด๊ฒฐ ๋˜๋Š” ๊ฒƒ์ด์—์š”.

 

 

์ด๋ ‡๊ฒŒ ํ•˜๊ณ  ๋‚˜๋‹ˆ ์ œ๊ฐ€ ์›ํ•˜๋Š” Test๋ฅผ ์ •์ƒ์ ์œผ๋กœ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์—ˆ๋˜ ๊ฒƒ์ด์—์š”.

 

๋ฐ˜์‘ํ˜•

DB๋ฅผ ํ™•์ธ ํ•ด ๋ณด๋‹ˆ ์•„์ฃผ ๋งŒ์กฑ์Šค๋Ÿฝ๊ฒŒ ์ž˜ ๋“ค์–ด๊ฐ„ ๊ฒƒ์ด์—์š”!

 

 

๐Ÿค” ์›์ธ ๋ถ„์„

๊ทธ๋ ‡๋‹ค๋ฉด ๋„๋Œ€์ฒด ์™œ? ์ € Annotaion์„ ์“ฐ์ง€ ์•Š์•˜์„ ๋•Œ ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ–ˆ๋˜ ๊ฒƒ์ผ๊นŒ์š”?

 

๊ทธ๊ฒƒ์€ ๋ฐ”๋กœ SpringBootTest๋ฅผ ์‚ฌ์šฉํ•ด์„œ Test๋ฅผ ์ง„ํ–‰ํ•˜๋ ค๊ณ  ํ•˜๋ฉด JUnit์ด ์ƒ์†ํ•˜๋ ค๋Š” SpringRunner Class๋ฅผ ์‚ฌ์šฉํ•ด์•ผ ํ•˜๋Š”๋ฐ, ์ด๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— Bean์œผ๋กœ ๋“ฑ๋กํ•˜๋ ค๊ณ  ํ–ˆ์—ˆ๋˜ PasswordEncoder๊ฐ€ ๋“ฑ๋ก๋˜์ง€ ์•Š์•„ ๊ฒฐ๊ณผ์ ์œผ๋กœ passoword๊ฐ€ NPE๊ฐ€ ๋ฐœ์ƒํ•œ ๊ฒƒ์ด์—์š”.

 

๐Ÿ’ก ์ฐธ๊ณ  ์ž๋ฃŒ :

@RunWith(SpringRunner.class)

1. @RunWith๋Š” JUnit Framwork๊ฐ€ Test๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ๋‚ด์žฅ๋œ Runner๋ฅผ ์‹คํ–‰.
2. @SpringBootTest๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด JUnit SpringJUnit4ClassRunner Class๋ฅผ ์ƒ์†๋ฐ›๋Š” @RunWith(SpringRunner.class)๋ฅผ ์ƒ์† ๋ฐ›์•„์„œ ์‚ฌ์šฉํ•ด์•ผ ํ•œ๋‹ค.

@SpringBootTest

1. ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋ฅผ ์ œ๊ณตํ•˜๋Š” ๊ธฐ๋ณธ์ ์ธ Annotation.
2. ์—ฌ๋Ÿฌ ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋‚˜์˜ ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ๋กœ ์ˆ˜ํ–‰ํ•˜๊ณ ์ž ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š”๋ฐ, ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ค์ •์„ ๋ชจ๋‘ Loadํ•˜๊ธฐ ๋•Œ๋ฌธ์— ์–ดํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ทœ๋ชจ๊ฐ€ ํด์ˆ˜๋ก ๋Š๋ ค์ง„๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.

@DataJpaTest

1. SpringBoot์—์„œ JPA๋ฅผ ํ…Œ์ŠคํŠธ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ œ๊ณตํ•˜๋Š” ๊ฒƒ.
2. ๋‹จ์œ„ ํ…Œ์ŠคํŠธ๊ฐ€ ๋๋‚  ๋•Œ ๋งˆ๋‹ค ์ž๋™์œผ๋กœ DB๋ฅผ RollBack ํ•ด์ค€๋‹ค.
3. In Memory DB๋ฅผ ์‚ฌ์šฉ.
4. ์‹ค์ œ DB์—์„œ ํ…Œ์ŠคํŠธ๋ฅผ ํ•˜๋ ค๊ณ  ํ•œ๋‹ค๋ฉด @AutoConfigureTestDatabase(replace = AutoConfigureTestDatabase.Replace.NONE)์„ ์ถ”๊ฐ€ ํ•ด์ฃผ์–ด์•ผ ํ•œ๋‹ค.

๊ธฐํƒ€

@SpringBootTest : ํ†ตํ•ฉ ํ…Œ์ŠคํŠธ, ์ „์ฒด - Bean ์ „์ฒด
@WebMvcTest : ๋‹จ์œ„ ํ…Œ์ŠคํŠธ, MVC ํ…Œ์ŠคํŠธ, MVC ๊ด€๋ จ Bean
@DataJpaTest : ๋‹จ์œ„ ํ…Œ์ŠคํŠธ, JPA ํ…Œ์ŠคํŠธ - JPA ๊ด€๋ จ Bean
@RestClientTest : ๋‹จ์œ„ ํ…Œ์ŠคํŠธ, Rest API ํ…Œ์ŠคํŠธ - ์ผ๋ถ€ Bean
@JsonTest : ๋‹จ์œ„ ํ…Œ์ŠคํŠธ, Json ํ…Œ์ŠคํŠธ - ์ผ๋ถ€ Bean

 

 

๐Ÿ“‘ ์ฐธ๊ณ  ์ž๋ฃŒ

https://n1tjrgns.tistory.com/224

 

728x90
๋ฐ˜์‘ํ˜•