Название может быть немного запутанным.
Скажем, у меня есть APIView
с post
методом.Внутри метода post я представил класс, у которого есть собственный метод.В данном случае это класс, который занимается загрузкой на S3, и это то, что я хочу пропустить при запуске unittest.
class SomeView(APIView):
def post(self):
# do something here
input1 = some_process(payload_arg1)
input2 = some_other_process(payload_arg2)
uploader = S3Uploader()
s3_response = uploader.upload_with_aux_fxn(input1, input2)
if s3_response['status_code'] == 200:
# do something else
return Response('Good job I did it!', status_code=200)
else:
return Response('noooo you're horrible!', status_code=400)
Реальный код имеет разные вызовы функций и ответы, очевидно.
Теперь мне нужно высмеять эти uploader
и uploader.upload_with_aux_fxn
, чтобы я на самом деле не звонил S3.Как мне поиздеваться?
Я пробовал в своем тестовом скрипте
from some_place import S3Uploader
class SomeViewTestCase(TestCase):
def setUp(self):
self.client = APIClient()
uploader_mock = S3Uploader()
uploader_mock.upload_support_doc = MagicMock(return_value={'status_code': 200, 'message': 'asdasdad'}
response = self.client.post(url, payload, format='multipart')
Но я все же запустил загрузку S3 (как показывает файл в S3).Как мне правильно подшучивать над этим?
EDIT1:
Моя попытка исправить
def setUp(self):
self.factory = APIRequestFactory()
self.view = ViewToTest.as_view()
self.url = reverse('some_url')
@patch('some_place.S3Uploader', FakeUploader)
def test_uplaod(self):
payload = {'some': 'data', 'other': 'stuff'}
request = self.factory.post(self.url, payload, format='json')
force_authenticate(request, user=self.user)
response = self.view(request)
, где FakeUplaoder
class FakeUplaoder(object):
def __init__(self):
pass
def upload_something(self, data, arg1, arg2, arg3):
return {'status_code': 200, 'message': 'unit test', 's3_path':
'unit/test/path.pdf'}
def downlaod_something(self, s3_path):
return {'status_code': 200, 'message': '', 'body': 'some base64
stuff'}
к сожалению этоне успешный.Я все еще использую класс
РЕДАКТИРОВАТЬ 2:
Я использую Django 1.11 и Python 2.7, на случай, если людям понадобится эта информация