我正在使用Django(1.10.5)和DRF(3.5.4)来创建API。我已经定义了一个处理文件上传的视图,并使用post请求中传递的数据和存储上载文件的临时文件的路径调用foo
方法。
class FooView(APIView):
parser_classes = (FormParser, MultiPartParser)
def post(self, request, format=None):
serializer = NewFooSerializer(data=request.data)
if serializer.is_valid():
file_obj = serializer.validated_data["my_file"]
name = serializer.validated_data["name"]
foo_id = my_module.foo(name=name, my_file=file_obj.temporary_file_path())
result_url = reverse('api:foo', kwargs={"foo_id": foo_id})
return Response({"result_url": result_url}, status=status.HTTP_202_ACCEPTED)
return Response(serializer.errors, status=status.HTTP_400_BAD_REQUEST)
我验证传入数据的序列化程序如下所示
class NewFooSerializer(serializers.Serializer):
name = serializers.CharField()
my_file = serializers.FileField()
基本上我想在没有使用mock
库的文件系统交互的情况下测试此视图。我目前的测试方法定义如下
@mock.patch('my_module.foo')
def test_post_should_invoke_foo_method(self, mocked_foo):
mocked_foo.return_value = "123456"
self.client.post(self.VIEW_URL,
{'my_file': self.file_mock,
'name': 'Test file'
}, format='multipart')
mocked_new.assert_called_with(name="Test file", my_file="/some/dummy/path"
这当然会引发AssertionError
AssertionError: Expected call: foo(my_file='/some/dummy/path', name='Test file')
Actual call: foo(my_file='/tmp/tmp0VrYgR.upload', name=u'Test file')
我找不到任何解决方法如何模拟TemporaryUploadedFile
所以我试图模拟这个类正在使用的tempfile.NamedTemporaryFile
。所以我在TestCase
named_temporary_file_mock = mock.MagicMock(spec=tempfile.NamedTemporaryFile)
named_temporary_file_mock.name = mock.MagicMock()
named_temporary_file_mock.name.return_value = "/some/dummy/path"
然后用
装饰我的测试方法@mock.patch('tempfile.NamedTemporaryFile', named_temporary_file_mock)
但不幸的是,这会导致与先前版本相同的错误。我可能会缺少什么?我应该采取另一种方法来避免与文件系统的交互吗?