I am writing a unittest. How can I patch self.conf in the init method in class MyValidator? In my unittest, I want to create a fake self.conf and get the response to make assertion of each element in self.conf.
class MyValidator(wsgi.Middleware):
def __init__(self, app):
self.app = app
self.conf = {
'auth_uri': CONF.someuri
'admin_domain_name': CONF.somedomainname,
'admin_user': CONF.someuser,
'admin_password': CONF.get_admin_password(),
'domain_name': CONF.somedomainname
}
For unittest, I am thinking to do.. (I know this is wrong.. but you get the idea)
@mock.patch('my_module.MyValidator.__init__.conf')
def setUp(self, mock_config):
@webob.dec.wsgify()
def fake_app(req):
return webob.Response()
self.request = webob.Request.blank('/')
mock_config = {
'auth_uri': 'testuri'
....
....
}
self.middleware = MyValidator(fake_app)
def test_auth_uri(self):
auth_uri = 'testuri'
env_auth_uri = self.request.environ.get('auth_uri', None)
self.assertEqual(auth_uri, env_auth_uri)
What should be done to patch self.conf to get intended response?
Even I'm using mocking and patching extensively I don't think your case need it. conf
is a MyValidator
's public attribute and you don't need anything more than change it as you need.
def setUp(self):
@webob.dec.wsgify()
def fake_app(req):
return webob.Response()
self.request = webob.Request.blank('/')
self.middleware = MyValidator(fake_app)
self.middleware.conf = {
'auth_uri': 'testuri'
....
....
}
In this case patch
cannot give to you nothing more because you are not interested about dict access and some smaller context where changes are made. If in some other test you need some other values you can use either self.middleware.conf.update(...)
or self.middleware.conf[...]=...
without change the behavior of other tests because setUp()
configure it in the same way for every tests.
Things become different if conf
is a read only property of MyValidator
(a little bit better design). In this case you need to patch it to make your test:
class MyValidator(wsgi.Middleware):
def __init__(self, app):
self.app = app
@property
def conf(self):
return {
'auth_uri': CONF.someuri
'admin_domain_name': CONF.somedomainname,
'admin_user': CONF.someuser,
'admin_password': CONF.get_admin_password(),
'domain_name': CONF.somedomainname
}
Where the test class should be
@mock.patch('my_module.MyValidator.conf', new_callable=PropertyMock)
def setUp(self, mock_conf):
@webob.dec.wsgify()
def fake_app(req):
return webob.Response()
self.request = webob.Request.blank('/')
mock_conf.return_value = {
'auth_uri': 'testuri'
....
....
}
self.middleware = MyValidator(fake_app)
def test_auth_uri(self):
auth_uri = 'testuri'
env_auth_uri = self.request.environ.get('auth_uri', None)
self.assertEqual(auth_uri, env_auth_uri)
Patch __init__()
is useful in rare cases. For instance when __init__
do some work and need resources that cannot be used or will not be used in test environment. An example of it is when init try to access to databases, use network resources, start new thread and so on.