Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to get an actual Pyramid request when unit testing

I have a Pyramid app that I'm still trying to learn. I'm supposed to write unit tests for it but I don't know how to build a request.

I see that Pyramid has a test module with a DummyRequest but this is blank and obviously if I pass that into the views it will fail because it's not populated with the attributes that the request would have while running.

So the question is, how to I pass a request that looks like a run-time request while testing?

like image 798
Jeff Avatar asked Nov 20 '12 23:11

Jeff


Video Answer


1 Answers

The thing to realize whenever you are unit testing (which is different from functional tests) is that you are testing a small "unit". This unit (your view in this case) does not require a "real" request, nor does it require a fully working system. That view has certain expectations of what an object calling itself a "request" may have, but that's about it, and it certainly doesn't require everything available in a real request. This is where mocking, or dummy objects come into play. You want to test your view, so you can pass something into your view with the properties it needs to check if it's doing the job. Let's say you have the following configuration:

def main():
    config = Configurator()
    config.add_route('user', '/users/{uid}')
    return config.make_wsgi_app()

@view_config(route_name='user', renderer='user_template.mako')
def user_view(request):
    uid = request.matchdict['uid']
    user = find_user(request, uid)
    if user is None:
        raise HTTPNotFound
    return {'user': user}

def find_user(request, uid):
    return request.db.query(User).filter_by(id=uid).first()

Great, so this is a real view and you'll notice that it only requires the request to have 2 attributes, matchdict and db. Well we can do that:

class Test_user_view(unittest.TestCase):
    def test_it(self):
        req = DummyRequest()
        req.db = DummyDB()
        req.matchdict = {'uid': '3'}
        result = user_view(req)
        self.assertEqual(result['user'].id, 3)

Now the one thing we don't address here is the implementation of DummyDB but a better approach might be to mock out find_user to return a dummy value. This keeps the test simple and focused on the view itself without getting bogged down in talking to the database. That's a separate test.

Other answers here cover functional testing more thoroughly and you should certain look at using WebTest to help with ensuring that your entire application is working as you expect it to, but this is not the realm of a unit test.

like image 162
Michael Merickel Avatar answered Oct 19 '22 00:10

Michael Merickel