2017-03-06 6 views
1

웹 응용 프로그램에서 MagicMock을 사용하여 테스트하고 있습니다. 함수는 모듈에서 직접 가져옵니다.nosetest가 테스트를 발견하면 Magic Mock이 실패합니다.

예상되는 동작은 테스트 할 함수가 호출 될 때 제 3 자 API를 호출하는 것입니다 (그러나 필자는이 테스트를 조롱하고 있습니다). 사전을 반환하고 테스트중인 함수가이를 객체에 삽입하고 객체를 반환합니다.

특정 테스트 모듈을 실행하는 데 nosetests를 사용하면 문제가 없습니다.

nosetests를 사용하여 내 test/unit/ 폴더에서 테스트를 검색하고 실행하면 테스트가 예상대로 작동하지 않습니다. 대신 조롱 된 API는 NoneType을 반환하고 테스트중인 함수는 Magic Mock 인스턴스를 반환합니다.

테스트 :

이 기능은 ( user_service 모듈) 테스트중인
def test_get_user_facebook_data_1(self): 
    facebook_oauth_response = {u'name': u'Jack Jacker', u'email': u'[email protected]', 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'[email protected]') 
    self.assertEquals(user_facebook_data._full_name, u'Jack Jacker') 

:

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 

하면 결과가 일치하지 않는 이유를 내가 이해하는 데 도움 주실 래요?

편집

새로운 정보 - 내가 직접 모듈에 nosetests를 사용하는 경우, 내가 테스트를 해요 함수가 유니 코드로 조롱 Facepy 사전 값을 액세스 (예상대로). 사용자가 nosetests를 사용하여 테스트를 발견 한 경우 또는 아래의 dm03514에 게시 된 솔루션을 사용하여 직접 테스트를 실행하는 경우이 함수는 조롱 된 Facepy API에서 Magic Mock 인스턴스로 사전에 액세스합니다. 의미, dict에 액세스하는 각각의 결과는 Magic Mock 인스턴스입니다.

return_value (모든 테스트에서)를 사전으로 설정 했으니 혼란 스럽습니다.

+0

업데이트 답변 : 테스트는 클래스가 아닌 get 메소드를 패치하고 있습니다. 인스턴스는'return_value'를 사용하여 참조 할 수 있습니다. – dm03514

답변

2

죄송 긴 하루, 그래서 일을 그들이 현재 방식으로 작업하는 이유는 정말 정신을 통해 구문 분석 할 수 없습니다 : P 관계없이 테스트가 실행되는 위치에 동일한 방식으로 수행함으로써 그것을 해결하는 그러나

이며, ~ patchfacepyuser_service 모듈로 가져 오기.

def test_get_user_facebook_data_1(self): 
    facebook_oauth_response = {u'name': u'Jack Jacker', u'email': u'[email protected]', u'id': u'sd5Jtvtk6'} 
    with mock.patch('module.path.to.user_service.facepy') as mock_facepy: 
     mock_facepy.GraphAPI.return_vaule.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'[email protected]') 
     self.assertEquals(user_facebook_data._full_name, u'Jack Jacker') 

상기 패치 facepy 로컬 user_service에 모듈.

+0

감사합니다. 이것은 물건을 조롱하는 똑똑한 방법처럼 보이지만 내 문제는 계속됩니다 (내 질문 업데이트). – JasTonAChair

+0

죄송합니다, 업데이트 됨, 반송 값을 잊어서, 작동해야합니다. 그래프 API가 인스턴스화되고 있기 때문에 모의 (Mock)은 당신이 패치하지 않고 인스턴스를 얻고 싶을 때 특정 클래스를 필요로하지 않는다. – dm03514

+0

다시 감사드립니다. 이 모듈을 사용하여 nosetests를 구체적으로 실행하면 작동하지만 nosetests에서 테스트를 발견하도록 허용하는 문제는 계속됩니다. 그럼에도 불구하고'return_value'에 대한 정보는 매우 유용합니다. – JasTonAChair

0

제 문제는 MagicMock에서 사전을 처리하는 방식에 대한 오해였습니다. 해당 __getitem__ 속성을 선언해야합니다.

필자가 언급 한 "불일치"는 내 테스트가 전혀 작동하지 않는 우연한 것일뿐입니다.

이것은 @ dm03514의 대답에서 크게 차용 한 것입니다.

def test_get_user_facebook_data_1(self): 
    facebook_oauth_response = {u'name': u'Jack Jacker', u'email': u'[email protected]', u'id': u'sd5Jtvtk6'} 
    with mock.patch('api.services.user_service.facepy') as mock_facepy: 

     # Mocking the response from the facepy. 
     # Setting this side effect allows the Mock object to be accessed as a dict. 
     def getitem(name): 
      return facebook_oauth_response[name] 
     mock_oauth = MagicMock() 
     mock_oauth.return_value = facebook_oauth_response 
     mock_oauth.__getitem__.side_effect = getitem 
     mock_facepy.GraphAPI.return_value.get = mock_oauth 

     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'[email protected]') 
     self.assertEquals(user_facebook_data._full_name, u'Jack Jacker')