Samples

dic includes several samples, see the github repository.

CherryPy Songs

Extending the CherryPy songs tutorial:

# Example of dic based on the CherryPy songs tutorial
# See https://cherrypy.readthedocs.org/en/3.3.0/tutorial/REST.html#getting-started

import cherrypy
import dic


class Song(object):
    def __init__(self, title, artist):
        self.title = title
        self.artist = artist

    def __repr__(self):
        return 'title: %s, artist: %s' % (self.title, self.artist)


class SongDatabase(object):
    def __init__(self, song_factory: dic.rel.Factory(Song)):
        self.song_factory = song_factory
        self.songs = {}

    def add_song(self, ident, title, artist):
        self.songs[ident] = self.song_factory(title=title, artist=artist)

    def __getitem__(self, ident):
        return self.songs[ident]

    def __str__(self):
        return self.songs.__str__()


class Songs:
    exposed = True

    def __init__(self, song_database: SongDatabase):
        self.songs = song_database
        self.songs.add_song('1', 'Lumberjack Song', 'Canadian Guard Choir')
        self.songs.add_song('2', 'Always Look On the Bright Side of Life', 'Eric Idle')
        self.songs.add_song('3', 'Spam Spam Spam', 'Monty Python')

    def GET(self, id=None):

        if id is None:
            return('Here are all the songs we have: %s' % self.songs)
        elif id in self.songs:
            song = self.songs[id]

            return(
                'Song with the ID %s is called %s, and the artist is %s' % (
                    id, song.title, song.artist))
        else:
            return('No song with the ID %s :-(' % id)


if __name__ == '__main__':
    builder = dic.container.ContainerBuilder()
    builder.register_class(Songs)
    builder.register_class(SongDatabase)
    builder.register_class(Song)

    container = builder.build()

    cherrypy.tree.mount(
        container.resolve(Songs), '/api/songs',
        {'/':
            {'request.dispatch': cherrypy.dispatch.MethodDispatcher()}
         }
    )

    cherrypy.engine.start()
    cherrypy.engine.block()

Mocking

dic wouldn’t be very useful if it didn’t help you test your code. A full example of using dic to inject mocks during tests:

This sample shows: 1. Mocking the database from a service 2. Using the new Python 3.3 mocking library (``unittest.mock`)

# Shows how unittest.mock can be used with dic to mock components during testing

import dic
import unittest, unittest.mock


class Database(object):
    def __init__(self):
        self.data = {
            '1': 'some data',
            '2': 'other data',
        }

    def get_data(self):
        return self.data


class Service(object):
    def __init__(self, database: Database):
        self.database = database

    def load(self):
        return self.database.get_data()


class ServiceTestCase(unittest.TestCase):
    """
    Test case for `Service` that mocks out the database.
    """
    def setUp(self):
        builder = dic.container.ContainerBuilder()
        builder.register_class(Service)

        # register a mock instead of the real database
        self.database_mock = unittest.mock.Mock(spec=Database)
        builder.register_instance(Database, self.database_mock)
        container = builder.build()

        self.service = container.resolve(Service)

    def test_get_data(self):
        # Arrange
        attrs = {'get_data.return_value': {'3': 'mocked data'}}
        self.database_mock.configure_mock(**attrs)

        # Act
        self.service.load()

        # Assert
        self.database_mock.get_data.called_once_with()

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