0

I'm currently learning how to write unit test for boto3

I'm trying to follow the moto documentation and have written a few lines for the unit test but it gave me error:

  @mock_s3
    def test_upload_to_s3(self):
        conn = boto3.resource('s3')
        # We need to create the bucket since this is all in Moto's 'virtual' AWS account
        conn.create_bucket(Bucket='mybucket')

        instance = s3_upload.upload_to_s3('test.csv', 'mybucket',
                                          'test.csv')
        instance.upload_to_s3()

        body = conn.Object(test.csv).get()['Body'].read().decode("utf-8")

        assert body == 'test.csv'


if __name__ == '__main__':
    unittest.main()

Error:AttributeError: 'NoneType' object has no attribute 'upload_to_s3'

I've been struggling with it for a whole day now, can someone gave me an example or some hints, thanks in advance.

wawawa
  • 2,835
  • 6
  • 44
  • 105
  • Have you considered using `moto`? https://github.com/spulec/moto – Oleksii Donoha Apr 20 '20 at 13:54
  • @OleksiiDonoha Could you provide an answer with ```moto``` based on my codes please? Many thanks. – wawawa Apr 20 '20 at 13:56
  • It looks like your test `test_upload_to_s3` isn't getting one of the arguments you've specified is required: `mock_s3_key`. What happens if you change your test method's signature to `def test_upload_to_s3(self, mock_upload_to_s3, mock_s3_key=None)`? – Josh Clark Apr 20 '20 at 14:00
  • @Josh It gave me error ```AttributeError: 'NoneType' object has no attribute 'return_value``` – wawawa Apr 20 '20 at 14:02
  • Why do you want `mock_s3_key` to be a parameter for your function? What do you want to pass into it? You get the `AttributeError` because your line `f"{mock_s3_key.return_value"}` is evaluating to `None.return_value`. What _is_ `mock_s3_key`? – Josh Clark Apr 20 '20 at 14:07
  • I've updated the original Python script @Josh (```s3_key``` is the filename with the timestamp) – wawawa Apr 20 '20 at 14:11
  • Moto's github README contains ready to use S3 example. You can easily adapt it for your use case. – Oleksii Donoha Apr 20 '20 at 14:11
  • @OleksiiDonoha yeah I've seen the example, it's quite different from my script, I've been trying to use it to fit into mine but seems not working....They have different parameters and structures...Sorry I'm totally new to Python and unit test, might need more hint.... – wawawa Apr 20 '20 at 14:13
  • @Cecilia Your code looks different now... What error do you get? It looks like it's almost there. You still haven't explained why mock_s3_key should be a test function parameter. – Josh Clark Apr 20 '20 at 14:15
  • @OleksiiDonoha I feel like I'm getting very close now, I updated my unit test by using ```moto```, but it gave me error ```AttributeError: 'NoneType' object has no attribute 'upload_to_s3'``` – wawawa Apr 20 '20 at 14:20
  • @Josh I took Oleksii's advice to use ```moto``` in the unit test, I've updated the codes and the error, would be great if you could take a look. Thanks. – wawawa Apr 20 '20 at 14:21
  • `'upload_to_s3` returns `None`. You assign this `None` to variable called `instance` and then try to call it once again by doing `instance.upload_to_s3()`. I don't see why you would do that, because naturally `None` has no attributes and you already called the function correctly the first time – Oleksii Donoha Apr 20 '20 at 14:57
  • I don't actually understand what those two lines ```instance = s3_upload.upload_to_s3('test.csv', 'mybucket', 'test_2020-04-12_12_02_30_raw.csv') instance.upload_to_s3()``` are doing, could you provide the working version of the unit test o that I can learn from it? – wawawa Apr 20 '20 at 15:10
  • I think that would be counterproductive. Also given that it's not clear what is the context of this code, it's hard to judge what should really be tested - existence of file, logging message, file contents etc. You've done a good progress so far so it's not out of your reach. – Oleksii Donoha Apr 20 '20 at 15:15

0 Answers0