0

I am using keystoneclient in my module to retrieve auth_token when user credential is passed. Then, put the token into req.headers['X-Auth-Token'] as below code. I want to write a unittest for this class. I am assuming that I need to mock Keystone authentication part. I am new to unittesting and mock so please help me understand how I should approach this.

from keystoneclient.v3 import client
from keystoneclient import exceptions as keystone_exceptions

class TokenChecker(wsgi.Middleware):

    def myrequest(self,req):
        try:
            token = self.check_credential(userid,password)
        except HTTPUnauthorized as e:
            return e

        req.headers['X-Auth-Token'] = token

    def check_credential(self, userid, password):
        keystone = client.Client(
            username            = foo
            password            = foo2
            user_domain_name    = foo3
            domain_name         = foo4
            auth_url            = foo5
            endpoint            = foo6
        )

        try:
            keystone.authenticate()
            return keystone.auth_token
        except (keystone_exceptions.AuthorizationFailure,
                keystone_exceptions.Unauthorized) as e:

            raise HTTPUnauthorized(e)

Unittest I created based on the answer I was provided,

    @mock.patch.object(TokenChecker, 'check_password', return_value= 'testtoken')
    def test_with_valid_auth_header(self,check_password_mock):
        req = webob.Request.blank('/')
        checker = TokenChecker(req)
        checker.process_request(req)
        self.assertNotEqual(req.headers['X-Auth-Token'], 1)

I think this is somewhat written wrong.. but I can't exactly tell. It is throwing me KeyError on X-Auth-Token. Could you please suggest a way to incorporate the provided answer into my code?

jaycee
  • 1
  • 1
  • 2
  • 9
  • please fix your code: 1 indentation; 2 `check_password` vs `check_credential`; 3 `userid` and `password` are not used in your method , is that the right behavior that you would test? We cannot write test if we don't understand the expected behavior. – Michele d'Amico Mar 09 '15 at 14:49
  • I'm sorry, I edited those. The idea is that when correct userid and password is passed to keystone client, it returns keystone.auth_token. This goes into req.headers['X-Auth-Token']. It would be very helpful if some one could explain how I should do unittest for this in details.. – jaycee Mar 09 '15 at 14:57

1 Answers1

1

You wrote 2 methods, so you need at least to write at least 2 unit tests. You also have try-except blocks, which means additional test for each exception, so in total 5 unit tests. I would mock check_credential in myrequest unit tests:

@mock.patch.object(TokenChecker, 'check_credential', return_value=1)
def test_myrequest_token_is_set(check_credential_mock):
    checker = TokenChecker()
    checker.myrequest(request)
    assert request.headers['X-Auth-Token'] == 1


@mock.patch.object(TokenChecker, 'check_credential')
def test_myrequest_is_unauthorized(check_credential_mock):
    check_credential_mock.side_effect = [HTTPUnauthorized]
    checker = TokenChecker()
    assert type(checker.myrequest(request)) == HTTPUnauthorized

and mock Client and calls to it in 2nd method.
Have a look here, to find out how to mock a class or you can also use mock.create_autospec(Client) (docs)

Community
  • 1
  • 1
matino
  • 17,199
  • 8
  • 49
  • 58