{"id":35,"date":"2022-04-22T02:21:02","date_gmt":"2022-04-22T02:21:02","guid":{"rendered":"https:\/\/blogs.oregonstate.edu\/codeislife\/?p=35"},"modified":"2022-04-22T05:22:55","modified_gmt":"2022-04-22T05:22:55","slug":"testing-persistence-with-abstract-repositories","status":"publish","type":"post","link":"https:\/\/blogs.oregonstate.edu\/codeislife\/2022\/04\/22\/testing-persistence-with-abstract-repositories\/","title":{"rendered":"Testing Persistence with Abstract Repositories"},"content":{"rendered":"\n<p>When it comes to testing your persistence implementations do you run into issues forming tests against databases while avoiding production code, but also dislike mocking to test your database calls? Try out an Abstract Repository!<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>import abc\nclass AbstractRepository(abc.ABC):\n    @abc.abstractmethod\n    def add(self, entity):\n        raise NotImplementedError\n        \n    @abc.abstractmethod(self, id):\n        raise NotImplementedError<\/code><\/pre>\n\n\n\n<p>Here&#8217;s an example of an Abstract Repository. At the most basic level we&#8217;ll want to add entities to our database and get entities from our database (by an id or other type of reference).<\/p>\n\n\n\n<p>For example, your real Repository could look like the following:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class RealRepository(AbstractRepository):\n\n    def __init__(self, database_session):\n        self.database_session = database_session\n        \n    def add(self, entity):\n        self.database_session.add(entity)\n        \n    def get(self, id):\n        self.database_session.query().filter(id)<\/code><\/pre>\n\n\n\n<p>Now to safely test against your database, you can simply create a fake Repository which implements the Abstract Repository and ask it to use either a smaller (in-memory) database or a different data structure entirely. You can then use this fake Repository in your unit tests and avoid using mocks to test your database calls.<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>class MyFakeRepository(AbstractRepository):\n\n    def __init__(self, list_of_entities: List):\n        self.entities = list_of_entities\n        \n    def add(self, entity):\n        self.entities.append(entity)\n        \n    def get(self, id):\n        for entity in self.entities:\n            if entity.id == id:\n                return entity<\/code><\/pre>\n\n\n\n<p>Here&#8217;s a unit test example to see how this works:<\/p>\n\n\n\n<pre class=\"wp-block-code\" style=\"font-size:11px\"><code>from my_fake_repository import MyFakeRepository\nclass TestCase(unittest.TestCase):\n\n    def test_database_get(self):\n        entity_1 = Entity(id=1)\n        entity_2 = Entity(id=2)\n        entity_3 = Entity(id=3)\n        entity_4 = Entity(id=4)\n        fake_repository = MyFakeRepository(&#091;entity_1, entity_2, entity_3, entity_4])\n        \n        expected = 3\n        result = fake_repository.get(expected)\n        self.assertEqual(result.id, expected, msg=\"result.id {result.id} does not equal {expected}\")<\/code><\/pre>\n\n\n\n<p>I hope you find this to be helpful! You can read more about the Repository Pattern in <em><a href=\"https:\/\/www.cosmicpython.com\/\">Architecture Patterns with Python<\/a><\/em>, written by Harry Percival and Bob Gregory.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>When it comes to testing your persistence implementations do you run into issues forming tests against databases while avoiding production code, but also dislike mocking to test your database calls? Try out an Abstract Repository! Here&#8217;s an example of an Abstract Repository. At the most basic level we&#8217;ll want to add entities to our database [&hellip;]<\/p>\n","protected":false},"author":12267,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-35","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/blogs.oregonstate.edu\/codeislife\/wp-json\/wp\/v2\/posts\/35","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blogs.oregonstate.edu\/codeislife\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blogs.oregonstate.edu\/codeislife\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/codeislife\/wp-json\/wp\/v2\/users\/12267"}],"replies":[{"embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/codeislife\/wp-json\/wp\/v2\/comments?post=35"}],"version-history":[{"count":12,"href":"https:\/\/blogs.oregonstate.edu\/codeislife\/wp-json\/wp\/v2\/posts\/35\/revisions"}],"predecessor-version":[{"id":47,"href":"https:\/\/blogs.oregonstate.edu\/codeislife\/wp-json\/wp\/v2\/posts\/35\/revisions\/47"}],"wp:attachment":[{"href":"https:\/\/blogs.oregonstate.edu\/codeislife\/wp-json\/wp\/v2\/media?parent=35"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/codeislife\/wp-json\/wp\/v2\/categories?post=35"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blogs.oregonstate.edu\/codeislife\/wp-json\/wp\/v2\/tags?post=35"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}