Moto: Mocking on a Class Level

Created on 5 Aug 2014  路  4Comments  路  Source: spulec/moto

Currently I have a bunch of tests that all send emails via ses:

import boto
from moto import mock_ses
class EmailTestCase(unittest.unitttest):
    @mock_ses
    def test_some_email_sending_function(self):
        conn = boto.connect_ses()
        conn = verify_email_identity("[email protected]")

        ... my test code

Now this works fine, but I find myself "setting up" moto the same way in all of my tests. Is there a recommended way to use moto on a class?

Based on the https://docs.python.org/3.5/library/unittest.mock-examples.html#applying-the-same-patch-to-every-test-method I think something like:

import boto
from moto import mock_ses
@mock_ses
class EmailTestCase(unittest.unitttest):
    conn = boto.connect_ses()
    conn = verify_email_identity("[email protected]")
    def test_some_email_sending_function(self):
        ... my test code

Would be pretty clean, thoughts?

Most helpful comment

For this type of thing, I'll usually do something like this

class MyTest(TestCase):
    def setUp(self):
        self.mock_ses = mock_ses()
        self.mock_ses.start()

    def test_email_sending(self):
        conn = boto.connect_ses()
        conn = verify_email_identity("[email protected]")
        ... my test code

    def tearDown(self):
        self.mock_ses.stop()

A class-based decorator is a good idea though that I will look into.

All 4 comments

For this type of thing, I'll usually do something like this

class MyTest(TestCase):
    def setUp(self):
        self.mock_ses = mock_ses()
        self.mock_ses.start()

    def test_email_sending(self):
        conn = boto.connect_ses()
        conn = verify_email_identity("[email protected]")
        ... my test code

    def tearDown(self):
        self.mock_ses.stop()

A class-based decorator is a good idea though that I will look into.

@spulec did the class based decorator get implemented? I thought it had at some point because I've even used it in a small project but testing it more vigorously now it doesn't appear to work and was thinking I was doing something wrong but can't find any examples of it being implemented.

@tomeliff Yes, it works pretty well now. I have it in my project like this:

@mock_autoscaling
@mock_ec2
@mock_elb
@mock_elbv2
@mock_iam
@mock_kms
@mock_logs
@mock_rds2
@mock_s3
@mock_sqs
@mock_sts
class BaseTestCase(unittest.TestCase):

Hi @JackDanger,

I tried to do the same :

import boto3
import logging
import unittest
from moto import mock_ec2


@mock_ec2
class TestBackupEbs(unittest.TestCase):
    """
    Test class for backupEbs.py
    """


    def __init__(self, region='eu-west-1', az='eu-west-1a', log_level='INFO'):
        """
        """

        ....
        self.aws_client = boto3.resource('ec2', region_name=self.region)
        ......

    def test_create_volume_snapshot(self):
        """
        This function test create_volume_snapshot.
        """

        self.logger.info('Starting test_create_volume_snapshot()')

        test_volume_to_backup_tags = [
            {
                'Key': 'Name',
                'Value': 'test_volume_to_backup'
            },
            {
                'Key': 'to_backup',
                'Value': 'true'
            }
        ]

        self.logger.info('Creating mocked volumes')
        test_volume_to_backup = create_ebs_volumes(self.aws_client,self.az, test_volume_to_backup_tags)
        self.logger.info('Mocked test_volume_to_backup %s created', test_volume_to_backup.id)

        volumes =  get_volumes_list(self.aws_client)
        create_volume_snapshot(self.aws_client, volumes)

        all_snapshots = self.aws_client.snapshots.all()

        volume_id_is_correct = False

        for snapshot in all_snapshots:
            if snapshot.volume_id == test_volume_to_backup.id:
                volume_id_is_correct = True

        assert volume_id_is_correct

I got the following error :

Failure: ValueError (Invalid endpoint: https://ec2.test_create_volume_snapshot.amazonaws.com) ... ERROR

======================================================================
ERROR: Failure: ValueError (Invalid endpoint: https://ec2.test_create_volume_snapshot.amazonaws.com)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/local/lib/python2.7/site-packages/nose/loader.py", line 523, in makeTest
    return self._makeTest(obj, parent)
  File "/usr/local/lib/python2.7/site-packages/nose/loader.py", line 570, in _makeTest
    return self.loadTestsFromTestCase(obj)
  File "/usr/local/lib/python2.7/site-packages/nose/loader.py", line 494, in loadTestsFromTestCase
    return super(TestLoader, self).loadTestsFromTestCase(testCaseClass)
  File "/usr/local/Cellar/python/2.7.14/Frameworks/Python.framework/Versions/2.7/lib/python2.7/unittest/loader.py", line 56, in loadTestsFromTestCase
    loaded_suite = self.suiteClass(map(testCaseClass, testCaseNames))
  File "/Users/hagerren/Documents/work/gitlab/microservices-infrastructure/paas-orchestration/lambda-functions/functions/backupEbs/tests/test_backupEbs.py", line 29, in __init__
    self.aws_client = boto3.resource('ec2', region_name=self.region)
  File "/usr/local/lib/python2.7/site-packages/boto3/__init__.py", line 92, in resource
    return _get_default_session().resource(*args, **kwargs)
  File "/usr/local/lib/python2.7/site-packages/boto3/session.py", line 389, in resource
    aws_session_token=aws_session_token, config=config)
  File "/usr/local/lib/python2.7/site-packages/boto3/session.py", line 263, in client
    aws_session_token=aws_session_token, config=config)
  File "/usr/local/lib/python2.7/site-packages/botocore/session.py", line 861, in create_client
    client_config=config, api_version=api_version)
  File "/usr/local/lib/python2.7/site-packages/botocore/client.py", line 73, in create_client
    verify, credentials, scoped_config, client_config, endpoint_bridge)
  File "/usr/local/lib/python2.7/site-packages/botocore/client.py", line 285, in _get_client_args
    verify, credentials, scoped_config, client_config, endpoint_bridge)
  File "/usr/local/lib/python2.7/site-packages/botocore/args.py", line 79, in get_client_args
    timeout=(new_config.connect_timeout, new_config.read_timeout))
  File "/usr/local/lib/python2.7/site-packages/botocore/endpoint.py", line 289, in create_endpoint
    raise ValueError("Invalid endpoint: %s" % endpoint_url)
ValueError: Invalid endpoint: https://ec2.test_create_volume_snapshot.amazonaws.com

Do you if I miss something ?

Was this page helpful?
0 / 5 - 0 ratings