I have a fairly complex app that uses celery, mongo, redis and pyramid. I use nose for testing. I’m not doing TDD (not test-first, at least), but I am trying very hard to get a decent amount of coverage. I’m stuck in the parts that are integrated with some of the above services. For example, I’m using redis for shared memory between celery tasks, but I’d like to be able to switch to memcache without too much trouble, so I’ve abstracted out the following functions:
import settings
db = StrictRedis(host=settings.db_uri, db=settings.db_name)
def has_task(correlation_id):
"""Return True if a task exists in db."""
return db.exists(str(correlation_id))
def pop_task(correlation_id):
"""Get a task from db by correlation_id."""
correlation_id = str(correlation_id) # no unicode allowed
task_pickle = db.get(correlation_id)
task = loads(task_pickle)
if task:
db.delete(correlation_id)
return task
def add_task(correlation_id, task_id, model):
"""Add a task to db"""
return db.set(str(correlation_id), dumps((task_id, model)))
I’m also doing similar things to abstract Mongo, which I’m using for persistent storage.
I’ve seen test suites for integrated web apps that run dummy http servers, create dummy requests and even dummy databases. I’m OK for celery and pyramid, but I haven’t been able to find dummies for mongo and redis, so I’m only able to run tests for the above when those services are actually running. Is there any way to provide dummy services for the above so I don’t have:
- to have external services installed and running, and
- to manually create and destroy entire databases (in-memory dummies can be counted on to cleanup after themselves)
I would suggest you use the mock library for such tasks. This allows you to replace your production objects (for example the database connection) with some pseudo objects which could be provided with some functionality needed for testing.
Example:
You can make assertions how your code interact with the mock, for example: