4

I have a project that uses a SOLR search engine through django-haystack. The search engine is on the different live server and touching it during the test run is undesirable (actually, it's impossible, since the access to that host is firewalled)

I'm using standard django testrunner. Luckily, it gives me the object test-settings I can modify to my liking, but turns out it's not the end of the story.

A lot of stuff in django-haystack is instantiated at the import-time, so by the time I change test-settings in my test runner it is too late, and despite the fact that I change the SEARCH_BACKEND to dummy, tests still make call to SOLR. The problem is not specific to HAYSTACK - same issue happens with mongoengine. Any class-level statements (eg CharField(default=Blah.objects.find(...))) are executed at the instantiation-time before django has a chance to change settings.

Of course the root of the problem is the fact that Django settings is a scary globally mutable mess and that Django provides no centralized place for the instantiation code. Given that, are there any suggestions on what testing solution will be the easiest? At the moment I'm thinking about a shell script which will change DJANGO_SETTINGS environment variable to test_settings and run ./manage.py test afterwards. It would be nicer if I could still do things via ./manage.py though.

Any better ideas? People with similar problems?

George Karpenkov
  • 2,094
  • 1
  • 16
  • 36
  • I know this probably doesn't help you much (and I'm disappointed as well) but apparently Django 1.4 will have capability to specify settings files. https://docs.djangoproject.com/en/dev/topics/testing/?from=olddocs#django.test.TestCase.settings For now though this SO answer is great http://stackoverflow.com/a/3519955/495154 – mattdeboard Mar 28 '12 at 18:45

1 Answers1

0

I took the answer from here and modified it slightly. This works great for me:

from contextlib import contextmanager

@contextmanager
def connection(**kwargs):
    from haystack import connections

    for key, new_value in kwargs.items():
        setattr(connections, key, new_value)
        connections['default'].options['URL'] = connections.connections_info['default']['URL']
    yield

My test, then, looks like:

def test_job_detail_by_title_slug_job_id(self):
    with connection(connections_info=solr_settings.HAYSTACK_CONNECTIONS):
        resp = self.client.get('/0/rts-crb-unix-production-engineer/27216666/job/')
        self.assertEqual(resp.status_code, 404)
        resp = self.client.get('/indianapolis/indiana/usa/jobs/')
        self.assertEqual(resp.status_code, 200)
Community
  • 1
  • 1
mattdeboard
  • 700
  • 1
  • 7
  • 17
  • 1
    I did a monkeypatch and it works also # monkey patch in haystack connection since override settings comes too late haystack.connections = haystack.loading.ConnectionHandler(HAYSTACK_CONNECTIONS) – dalore Jul 31 '14 at 12:16