I'm using MagicMock to test a function in a web app. The function is imported directly from a module.
The expected behaviour is: when the function being tested is called, it calls on a third party api (but I'm mocking this for my test). That returns a dictionary and the function under test inserts that into an object and returns the object.
That works fine when I use nosetests to run that specific module of tests.
When I use nosetests to discover and run tests in my test/unit/
folder, the test doesn't work as expected. Instead the mocked API returns a NoneType
and the function being tested returns a Magic Mock instance.
The test:
def test_get_user_facebook_data_1(self):
facebook_oauth_response = {u'name': u'Jack Jacker', u'email': u'jack@jack.jack', u'id': u'sd5Jtvtk6'}
facepy.GraphAPI.get = MagicMock(return_value=facebook_oauth_response)
user_facebook_data = user_service.get_user_facebook_data('bogus_facebook_oauth_access_token')
self.assertEquals(user_facebook_data._facebook_oauth_id, u'sd5Jtvtk6')
self.assertEquals(user_facebook_data._email, u'jack@jack.jack')
self.assertEquals(user_facebook_data._full_name, u'Jack Jacker')
The function being tested (in user_service
module):
def get_user_facebook_data(facebook_access_token):
'''
With a user's FB access token, retrieve their credentials to either create a new account or login. Create a user object from the user model, but don't save
'''
try:
graph = facepy.GraphAPI(facebook_access_token)
facebook_data = graph.get('me?fields=id,name,email')
except facepy.exceptions.OAuthError:
raise errors.FacebookAccessTokenInvalidError()
user = user_model.User()
try:
facebook_oauth_id = facebook_data[u'id']
user.set_new_fb_oauth(facebook_oauth_id)
except KeyError:
raise errors.OauthNoIdError()
try:
email = facebook_data[u'email']
user.set_new_email(email)
except KeyError:
pass
try:
full_name = facebook_data[u'name']
user.set_new_full_name(full_name)
except KeyError:
pass
return user
Can you please help me understand why the result is inconsistent?
EDIT
New information - if I use nosetests on the module directly, the function I'm testing accesses the mocked Facepy dictionary values as unicode (as expected). If I user nosetests to discover tests, or if I use the solution posted by dm03514 below and run the tests directly, the function accesses the dictionary from the mocked facepy API as Magic Mock instances. Meaning, each result of accessing the dict is an Magic Mock instance.
That's confusing, as I set the return_value (in all tests) to be the dictionary.