Achim
Achim

Reputation: 15702

Create pyramid request for testing, so that events are triggered

I would like to test a pyramid view like the following one:

def index(request):
    data = request.some_custom_property.do_something()
    return {'some':data}

some_custom_property is added to the request via such an event handler:

@subscriber(NewRequest)
    def prepare_event(event):
        event.request.set_property(
            create_some_custom_property,
            'some_custom_property',reify=True
        )

My problem is: If I create a test request manually, the event is not setup correctly, because no events are triggered. Because the real event handler is more complicated and depends on configuration settings, I don't want to reproduce that code in my test code. I would like to use the pyramid infracstructure as much as possible. I learned from an earlier question how to set up a real pyramid app from an ini file:

from webtest import TestApp
from pyramid.paster import get_app

app = get_app('testing.ini#main')
test_app = TestApp(app)

The test_app works fine, but I can only get back the html output (which is the idea of TestApp). What I want to do is, to execute index in the context of app or test_app, but to get back the result of index before it's send to a renderer.

Any hint how to do that?

Upvotes: 0

Views: 653

Answers (1)

zaquest
zaquest

Reputation: 2050

First of all, I believe this is a really bad idea to write doctests like this. Since it requires a lot of initialization work, which is going to be included in documentation (remember doctests) and will not "document" anything. And, to me, these tests seems to be the job for unit/integration test. But if you really want, here's a way to do it:

import myapp
from pyramid.paster import get_appsettings
from webtest import TestApp
app, conf = myapp.init(get_appsettings('settings.ini#appsection'))
rend = conf.testing_add_renderer('template.pt')
test_app = TestApp(app)
resp = test_app.get('/my/view/url')
rend.assert_(key='val')

where myapp.init is a function that does the same work as your application initialization function, which is called by pserve (like main function here. Except myapp.init takes 1 argument, which is settings dictionary (instead of main(global_config, **settings)). And returns app (i.e. conf.make_wsgi_app()) and conf (i.e pyramid.config.Configurator instance). rend is a pyramid.testing.DummyTemplateRenderer instance.

P.S. Sorry for my English, I hope you'll be able to understand my answer.

UPD. Forgot to mention that rend has _received property, which is the value passed to renderer, though I would not recommend to use it, since it is not in public interface.

Upvotes: 2

Related Questions