2017-03-06 6 views
1

私はMagicMockを使用してWebアプリケーションの機能をテストしています。関数はモジュールから直接インポートされます。nosetestがテストを検出するとMagic Mockが失敗する

予想される動作は、テスト対象の関数が呼び出されたときに、サードパーティのAPIを呼び出していることです(ただし、私はテストのためにこれを嘲笑しています)。これは辞書を返し、テスト中の関数はそれをオブジェクトに挿入してオブジェクトを返します。

nosetestsを使用してテストの特定のモジュールを実行するとうまく動作します。

nosetestsを使用してtest/unit/フォルダのテストを検出して実行すると、テストが正常に機能しません。代わりに模擬APIはNoneTypeを返し、テストされる関数はMagic Mockインスタンスを返します。

テスト:

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

user_serviceモジュールで)テストされている機能:

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 

あなたは結果が矛盾している理由を私は理解して助けてくださいことはできますか?

EDIT

新情報 - 私は直接モジュール上nosetestsを使用する場合(予想通り)、私はテストだ関数はUnicodeとして嘲笑Facepy辞書値にアクセスします。ユーザーがテストを見つけるためにnosetestsした場合、または以下のdm03514によって投稿されたソリューションを使用してテストを直接実行すると、関数はmocked 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') 

user_serviceモジュールにfacepyローカル上記パッチ。

+0

私はこれを試してみました。ありがとうございます。これは物事を模擬するスマートな方法のように見えますが、私の問題は解決しません(私の質問を更新しました)。 – JasTonAChair

+0

申し訳ありませんが、更新されました、戻り値を忘れました、今すぐ動作するはずです。グラフAPIはインスタンス化されているので、インスタンスではなくクラスにパッチを当てる方法を模擬する必要があります。 – 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') 
関連する問題