I hate when my unittest hits database. Especially when each test case needs different dataset.
So I wrote this db mock, that's local to specific test and uses sqlite3 in-memory db.
Usage (nosetests):
class TestMainNoData(DbMock):
'testing main function with no meaningful data'
def test_no_posts(self):
'there are no posts'
assert models.Post.objects.count() == 0, 'should be no feeds'
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 | # -*- coding: utf-8 -*-
'''
# $Id: django_db_mockup.py 375 2007-07-25 10:45:14Z akhavr $
'''
import copy
import django.conf
from django.core.management import syncdb
from django.db import backend, connection
import django.db.backends.sqlite3.base as django_sqlite
from django.db.backends import util
from pysqlite2 import dbapi2 as sqlite
def temp_django_db_conn():
'create temporary django db connection'
sqlite_conn = django_sqlite.DatabaseWrapper()
sqlite_conn.connection = sqlite.connect(
database=':memory:',
detect_types=sqlite.PARSE_DECLTYPES | sqlite.PARSE_COLNAMES)
# define some functions that are missing from sqlite
sqlite_conn.connection.create_function('concat', 2,
lambda *args: ''.join(args))
return sqlite_conn
def subst_django_db_conn(new_conn):
'''
substitute django db connection by <new_conn>
warning: black magic involved
'''
# black magic ;)
klass = connection.__class__
orig_conn = klass.__new__(klass)
orig_conn.__dict__.update(connection.__dict__)
connection.__class__ = new_conn.__class__
connection.__dict__.update(new_conn.__dict__)
return orig_conn
class DbMock:
def setup(self):
'db mockup setup'
self.sqlite_conn = temp_django_db_conn()
self.orig_conn = subst_django_db_conn(self.sqlite_conn)
self.orig_db_engine = django.conf.settings.DATABASE_ENGINE
django.conf.settings.DATABASE_ENGINE = 'sqlite3'
self.orig_db_name = django.conf.settings.DATABASE_NAME
django.conf.settings.DATABASE_NAME = ':memory:'
self.supports_constraints = backend.supports_constraints
backend.supports_constraints = False
self.operator_mapping = copy.deepcopy(backend.OPERATOR_MAPPING)
backend.OPERATOR_MAPPING.update(django_sqlite.OPERATOR_MAPPING)
syncdb(verbosity=0, interactive=False)
return
def teardown(self):
'db mockup teardown'
subst_django_db_conn(self.orig_conn)
django.conf.settings.DATABASE_ENGINE = self.orig_db_engine
django.conf.settings.DATABASE_NAME = self.orig_db_name
backend.supports_constraints = self.supports_constraints
backend.OPERATOR_MAPPING = self.operator_mapping
return
|
More like this
- Template tag - list punctuation for a list of items by shapiromatron 8 months, 4 weeks ago
- JSONRequestMiddleware adds a .json() method to your HttpRequests by cdcarter 9 months ago
- Serializer factory with Django Rest Framework by julio 1 year, 3 months ago
- Image compression before saving the new model / work with JPG, PNG by Schleidens 1 year, 4 months ago
- Help text hyperlinks by sa2812 1 year, 5 months ago
Comments
Several reasons:
I've not been into django testing framework because I use django from 0.91 era when it had none (and wasn't always following django-users :) So I'll look deeper into django's testing framework to see how it could be twisted to do what I need.
#
Please login first before commenting.