【问题标题】:Mock test case to upload file to S3模拟测试用例将文件上传到 S3
【发布时间】:2017-09-14 01:17:36
【问题描述】:

我们如何模拟文件上传到 S3。我尝试过这样的事情。

file_mock = mock.MagicMock(spec=File, name='FileMock')
@mock.patch('storages.backends.s3boto.S3BotoStorage', FileSystemStorage)
def test_post_file(self):
    response = self.client.post('/api/v1/file_upload/', {
                "status": "NEW",
                "amount": "250.00",
                "bill": file_mock
            })

但这反过来实际上是上传到 S3。我是新手。不上传文件到 S3 怎么实现?

【问题讨论】:

    标签: python django unit-testing amazon-s3 mocking


    【解决方案1】:

    所以你的一般方法是正确的,但你需要覆盖 boto 的行为。所以你需要为它创建多个补丁。这样的事情可能会起作用:

    """
    Mock Connection class for Bucket
    """
    class MockConnection():
        def __init__(self):
            self.provider = 'AWS'
    
        def delete_key(self, param):
            pass
    
    """
    Mock Connection class which is called for connecting to s3
    """
    class MockS3Connection():
        def get_bucket(self, name, validate=False):
            return Bucket(MockConnection(), 'bucket')
    
    """
    Mock Key class which also gets the bucket
    """
    class MockKey():
        def __init__(self, bucket):
            self.bucket = bucket
    
        def set_contents_from_string(self, data, headers):
            pass
    
        def set_acl(self, read):
            pass    
    """
    Mock the function which connects to S3
    """
    def mock_connect_s3():
        return MockS3Connection()
    
    class TestUploadResource(BaseResourceTestCase):
        """
        Test Document upload
        """
        def setUp(self):
            super(TestUploadResource, self).setUp()
    
        @mock.patch('boto.connect_s3', new = mock_connect_s3)
        @mock.patch("boto.s3.key.Key", MockKey)
        def test_file_is_accepted(self):
            '''
            Test case to check whether file is uploaded
            '''
            name = raw_input('Document1')+'.pdf'
            file = open(name,'rw')   # Trying to create a new file or open one
    
            """
            Call the upload docs command with the file which 
            we want to save
            """
            response = self.client.post('some-url')
    
            """
            Check whether the file is going and the response of creation
            is coming or not
            """
            self.assertEqual(201, response.status_code)
    

    然后,您可以在函数中添加各种东西作为预期的行为。希望这会有所帮助。

    【讨论】:

      【解决方案2】:

      上述解决方案有效。我也不得不模拟保存方法。

      @mock.patch.object(<Model>, 'save')
      @mock.patch('boto.connect_s3', new=mock_connect_s3)
      @mock.patch("boto.s3.key.Key", MockKey)
      def test_post_file(self, save_mock):
        response = self.client.post('/api/v1/file_upload/', {
                  "status": "NEW",
                  "amount": "250.00",
                  "bill": file_mock
              })
        self.assertTrue(save_mock.called)
        self.assertEqual(201, response.status_code)
      

      【讨论】:

        【解决方案3】:

        经过大量研究,目前我发现的最简单的解决方案是在 setUp 方法中甚至在测试文件的顶部对 FileField 进行猴子修补。

        例子:

        from django.core.files.storage import FileSystemStorage
        from myapp.models import Report
        
        class TestUploadS3(TestCase):
        
            def setUp(self):
                ...
                Report.pdf_file.field.storage = FileSystemStorage()
                ...
        

        这样文件不会上传到S3。

        【讨论】:

          【解决方案4】:

          根据上面的答案,我们可以使用补丁来确保我们在补丁模型中拥有正确的属性

              from unittest.mock import patch
              from django.core.files.storage import FileSystemStorage
          
              with patch('my_app.models.Mymodel.file_field.field.storage', FileSystemStorage()):
                ...test file behavior code
          
          

          【讨论】:

            猜你喜欢
            • 2013-10-24
            • 1970-01-01
            • 2019-06-14
            • 1970-01-01
            • 2022-12-22
            • 1970-01-01
            • 1970-01-01
            • 2017-08-30
            • 2017-10-07
            相关资源
            最近更新 更多