Repository: boto/boto3
File: tests/unit/resources/test_factory.py (Python)

Code before:
        defs = {
            'Group': {
                'subResources': {
                    'identifiers': {'GroupId': 'Id'},
                    'resources': ['Instance']
                }
            },
            'Subnet': {
                'identifiers': [{'name': 'Id'}]
            }
        }
        service_model = ServiceModel({
            'shapes': {
                'InstanceShape': {
                    'type': 'structure',
                    'members': {
                        'GroupId': {
                            'shape': 'String'
                        },
                        'SubnetId': {
                            'shape': 'String'
                        }
                    }
                },
                'String': {
                    'type': 'string'
                }
            }
        })

        resource = self.load('test', 'Instance', model, defs,
                             service_model)('group-id')

        # Load the resource with no data
        resource.meta['data'] = {}

        self.assertIn('subnet', dir(resource),
                      'Resource should have a subnet reference')
        self.assertIsNone(resource.subnet,
                          'Missing identifier, should return None')
        self.assertIn('group', dir(resource),
                      'Resource should have a group reverse ref')

        # Load the resource with data to instantiate a reference
        resource.meta['data'] = {'SubnetId': 'abc123'}
        self.assertIsInstance(resource.subnet, ServiceResource)
        self.assertEqual(resource.subnet.id, 'abc123')

    @mock.patch('boto3.resources.factory.CollectionManager')
    @mock.patch('boto3.resources.model.Collection')
    def test_resource_loads_collections(self, mock_model, collection_cls):

Review comment (bug):
Let's not mask potential bugs.  It seems completely reasonable that hasattr should work, so if we are going to change it we should understand why.  I'm not really comfortable saying that we have no idea why it works let's just leave it as is, especially given this seems pretty straightforward to track down why.


Code after:
        defs = {
            'Group': {
                'identifiers': [{'name': 'Id'}],
                'subResources': {
                    'identifiers': {'Id': 'GroupId'},
                    'resources': ['Instance']
                }
            },
            'Subnet': {
                'identifiers': [{'name': 'Id'}]
            }
        }
        service_model = ServiceModel({
            'shapes': {
                'InstanceShape': {
                    'type': 'structure',
                    'members': {
                        'GroupId': {
                            'shape': 'String'
                        },
                        'SubnetId': {
                            'shape': 'String'
                        }
                    }
                },
                'String': {
                    'type': 'string'
                }
            }
        })

        resource = self.load('test', 'Instance', model, defs,
                             service_model)('group-id')

        # Load the resource with no data
        resource.meta['data'] = {}

        self.assertTrue(hasattr(resource, 'subnet'),
                        'Resource should have a subnet reference')
        self.assertIsNone(resource.subnet,
                          'Missing identifier, should return None')
        self.assertTrue(hasattr(resource, 'group'),
                        'Resource should have a group reverse ref')

        # Load the resource with data to instantiate a reference
        resource.meta['data'] = {'SubnetId': 'abc123'}
        self.assertIsInstance(resource.subnet, ServiceResource)
        self.assertEqual(resource.subnet.id, 'abc123')

    @mock.patch('boto3.resources.factory.CollectionManager')
    @mock.patch('boto3.resources.model.Collection')