2차 프로젝트: 중간 정리 (4)

Hyeon Soo·2021년 3월 11일
0

유닛 테스트를 함에 있어서 데이터베이스에 한글 문자가 저장되지 않는 현상이나, 외부 서버와 통신하는 View 작성시 유닛 테스트를 할 때 고려해야 할 점에 대해서 정리해보고자 한다.

1. DB 문자 설정

본래 유닛 테스트를 실행할 때는, 앱의 models.py들을 이용하여 실제 db와 동일한 설정의 test db를 생성하여 테스트를 진행하고, 테스트의 종료와 함께 db를 삭제한다. 하지만 경우에 따라 로컬 db와 달리 테스트 db가 문자를 제대로 받지 못하는 현상이 생기는데, 아래와 같이 TEST 부분을 추가로 설정해주면 된다.

DATABASES = {
        'default': {
            'ENGINE': 'django.db.backends.mysql',
            'NAME': 'YOUR_DATABASE_NAME',
            'USER': 'YOUR_USER',
            'PASSWORD': 'YOUR_PASSWORD',
            'HOST': '127.0.0.1', 
            'PORT': '',
            'TEST': {
                'CHARSET': 'utf8',
                'COLLATION': 'utf8_general_ci',
            }
        }
    }

2. 외부 서버와의 통신할 때의 유닛 테스트

유닛테스트의 중요한 점은 다른 기능과의 의존이 없이 단독으로 실행되어 성공해야 한다는 점이다. 이때, 소셜 로그인, s3이미지 업로드, 삭제 등 외부 서버와의 통신이 필요한 기능들을 유닛테스트 할 경우, 외부 서버의 상태나 프로젝트 디렉토리의 폴더 상황에 관계없이 테스트가 동작해야 한다. 이를 위해서는 view에서 외부서버에 보내는 요청을 대체해주어야 할 필요가 있고, 파일 업로드 기능 등의 경우 테스트 할 때마다 목 파일을 생성해주어야 한다.
첫 번째의 경우, unittest.mock의 patch를 이용해줄 수 있다. 이것을 실행하고자 하는 테스트 메소드에 데코레이터로 붙여주어 대체하고자 하는 요청을 설정해주고, 필요한 경우 메소드 안에 대체된 요청의 response를 임의로 생성해주면, 실제 서버에 통신하지 않고 코드의 동작 여부를 확인할 수 있다. 예를 들어

 @patch('resume.views.boto3')#원래 view의 boto3를 대체
    def test_post_success(self, mock_s3_client):
        file      = mock.MagicMock(spec=File, name='file.pdf')#mock파일을 생성
        file.name = 'file.pdf'
        class MockedResponse:#응답을 임의로 mock으로 생성
            def json(self):
                return None
        mock_s3_client.upload_fileobj = MagicMock(return_value=MockedResponse())#요청을 보내는 부분을 대체 응답으로 대신함
        user                          = User.objects.get(id=1)
        token                         = jwt.encode({'id': user.id}, SECRET_KEY, algorithm=ALGORITHM)
        client                        = Client()
        data                          = {'resume': file}
        response                      = client.post('/resume/upload', data, **{'HTTP_Authorization': token})
        self.assertEqual(response.status_code, 200)
        self.assertEqual(response.json(), {'message': 'SUCCESS', 'data': ResumeFile.objects.get(user=user).file_url})

이상으로 테스트를 해 볼 수 있다. 또한, mock.MagicMock을 이용하여 목 파일을 생성하여 사용할 수 있다.

0개의 댓글