在Python unittest中模拟外部REST

时间:2015-03-09 14:25:57

标签: python mocking unit-testing keystone

我在模块中使用keystoneclient在传递用户凭据时检索auth_token。然后,将令牌放入req.headers ['X-Auth-Token'],如下面的代码。我想为这堂课写一个单元测试。我假设我需要模拟Keystone身份验证部分。我是单元测试和模拟的新手,所以请帮助我理解我应该如何处理这个问题。

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)

我根据提供的答案创建的单元测试

    @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)

我认为这有些错误。但我无法确切地说出来。它在X-Auth-Token上抛出了KeyError。您能否建议一种方法将提供的答案合并到我的代码中?

1 个答案:

答案 0 :(得分:1)

您编写了2种方法,因此至少需要编写至少2个单元测试。 您还有try-except块,这意味着对每个异常进行额外测试,因此总共有5个单元测试。 我会在check_credential单元测试中模拟myrequest

@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

并模拟Client并在第二种方法中调用它 看看here,了解如何模拟课程,或者也可以使用mock.create_autospec(Client)docs