ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • 2023년 1월 8일
    Today I Learned 2023. 1. 8. 12:38

    Jest

    특정 입력 컴포넌트가 disabled인지 확인하고 싶을 때에는

     

    toHaveAttribute와 closest를 Test에서 사용할 수 있음

     

    expect(screen.getByPlaceholderText('선택된 장소 이름')
      .closest('input')).toBeDisabled();
    expect(screen.getByPlaceholderText('선택된 장소 주소')
      .closest('input')).toBeDisabled();

     

    reference

    - https://stackoverflow.com/questions/56593840/check-that-button-is-disabled-in-react-testing-library

     

     

    msw에서 PathVariable을 받는 API 요청의 순서를 유의하자.

    다음과 같은 API 요청들이 있고, msw로 경로가 '/places/search'에 해당하는 요청을 mocking해 처리하려고 하는 상황을 가정

     

    // src/services/PlaceApiService.js
    
    export default class PlaceApiService {
      async fetchPlace(placeId) {
        const url = `${apiBaseUrl}/places/${placeId}`;
        const { data } = await axios.get(url);
        return data;
      }
    
      async searchPlace(placeNameSearching) {
        const url = `${apiBaseUrl}/places/search`;
        const { data } = await axios.get(url, {
          params: {
            keyword: placeNameSearching,
          },
        });
        return data;
      }
    }
    // src/testServer.js
    
    import { rest } from 'msw';
    import { setupServer } from 'msw/node';
    
    import config from './config';
    
    const { apiBaseUrl } = config;
    
    const testServer = setupServer(
      // fetchPlace
      rest.get(
        `${apiBaseUrl}/places/:placeId`,
        async (request, response, context) => {
          const { placeId } = await request.params;
    
          if (placeId === '1') {
            return response(
              context.status(200),
              context.json(
                // ...
              ),
            );
          }
    
          if (placeId === '4444') {
            return response(
              context.status(404),
              context.json(
                // ...
              ),
            );
          }
    
          return response(
            context.status(400),
          );
        },
      ),
    
      // searchPlace
      rest.get(
        `${apiBaseUrl}/places/search`,
        async (request, response, context) => {
          const placeName = await request.url.searchParams.get('keyword');
    
          if (placeName === '대구') {
            return response(
              context.status(200),
              context.json(
                // ...
              ),
            );
          }
    
          return response(
            context.status(400),
          );
        },
      ),
    );
    
    export default testServer;
    // src/stores/PostFormStore.test.js
    
    context('운동 장소를 검색하는 함수가 호출되면', () => {
      beforeEach(() => {
        postFormStore.placeNameSearching = '대구';
      });
    
      it('반환되는 검색된 장소 배열을 상태로 저장 후 publish', async () => {
        await postFormStore.searchPlace();
    
        const { searchedPlaces } = postFormStore;
        expect(searchedPlaces.length).toBe(2);
      });
    });

     

    이렇게 테스트를 진행할 경우 테스트 코드에서 수행하려는 테스트는 실패

     

    동료분의 도움을 받아 찾아낸 이유에는 두 가지가 있었음.

     

    1. msw는 요청으로 주어진 경로를 setupServer() 메서드에 정의된 rest()들을 순서대로 확인하면서, 요청 URL이 일치하는 rest()를 하나씩 탐색

     

    2. Store 테스트 코드에서 실행한 테스트의 요청은, 요청 URL로

    `${apiBaseUrl}/places/:placeId`

    을 받는 rest()에서 요청을 받고 있었음.

     

    따지고 보면

    `${apiBaseUrl}/places/search`

    의 'search' 역시 :placeId의 Path Varibale이 되지 못할 이유가 없음, Path Varibale은 숫자뿐만 아니라 당연히 문자열이 될 수도 있기 때문

    따라서 두 rest()의 순서를 바꿔 요청 URL이 정확히 /places/search 인 경우를 처리하는 rest()가 먼저 오게 하고, 그 외의 /place/무언가 형태의 요청 URL들은 그 뒤의 places/:placeId 에서 받도록 하는 것으로 문제를 해결

     

    // src/testServer.js의 setupServer 내부를 다음과 같이 수정
    
    // searchPlace
    rest.get(
      `${apiBaseUrl}/places/search`,
      async (request, response, context) => {
        const placeName = await request.url.searchParams.get('keyword');
    
        if (placeName === '대구') {
          return response(
            context.status(200),
            context.json(
              // ...
            ),
          );
        }
    
        return response(
          context.status(400),
        );
      },
    ),
      
    // fetchPlace
    rest.get(
      `${apiBaseUrl}/places/:placeId`,
      async (request, response, context) => {
        const { placeId } = await request.params;
    
        if (placeId === '1') {
          return response(
            context.status(200),
            context.json(
              // ...
            ),
          );
        }
    
        if (placeId === '4444') {
          return response(
            context.status(404),
            context.json(
              // ...
            ),
          );
        }
    
        return response(
          context.status(400),
        );
      },
    ),

     

     

    docker에서 <none> image 삭제

    docker rmi $(docker images -f "dangling=true" -q)

     

    • dangling: TAG가 없는 (none) 이미지만 필터링
    • -f "dangling=true": dangling=true인 이미지들만 검색
    • -q: 이미지의 ID를 가져옴

     

    reference

    - https://jhkimmm.tistory.com/9

     

     

     

    React 컴포넌트가 렌더링하는 요소가 없는 경우를 테스트하는 경우

    describe('PostsSearchSetting', () => {
      function renderPostsSearchSetting() {
        return render((
          <PostsSearchSetting />
        ));
      }
        
      context('검색조건 설정 컴포넌트가 활성화되어 있지 않으면', () => {
        beforeEach(() => {
          searchSettingMode = false;
        });
    
        it('컴포넌트를 출력하지 않음', () => {
          const { container } = renderPostsSearchSetting();
    
          expect(container.childElementCount).toBe(0);
        });
      });
    });

     

    reference

    - https://dev.to/twinfred/using-jest-to-check-that-a-react-component-doesn-t-render-22j1

     

     

     

     

    'Today I Learned' 카테고리의 다른 글

    WebSocket을 이용한 실시간 채팅 구현하기 3: STOMP  (0) 2023.01.21
    Java에서 단일 Key, Value 쌍 사용하기: Map.Entry<K, V>  (0) 2023.01.20
    2023년 1월 7일  (0) 2023.01.07
    2023년 1월 6일  (0) 2023.01.06
    2023년 1월 5일  (0) 2023.01.05

    댓글

Designed by Tistory.