2017-05-25 15 views
0

Flaskアプリケーション用のテストモジュールを作成しています。このResourceのget()メソッドでは、Mongoからデータを取得し、それを繰り返して出力を生成します。コレクションのfind()メソッドを嘲笑して、iterableを返します。問題は、get()内部でiterableをループするところ、空であるかのようにスキップすることです。だから、私はテストの中でiterableをループしてみました。そして、私はそれが含むべき3つのdictsを正常に見ることができます。Python Mock Iterable(ソート)が動作しない

クラスのプロパティ:

class _TestAll(BaseAllReports): 
    collection = MagicMock() 
    bool_columns = ('bool1', 'bool2') 
    string_set_columns = ('string1', 'string2') 
    int_columns = ('int1', 'int2') 
    text_columns = ('text1', 'text2') 
    stats_columns = ('bool1', 'int1') 

Resource.get():

def get(self): 
    args = self.parser().parse_args() 
    search = self.search_doc(args) 

    docs = self.collection.find(search, {'_id': False}) 
    print(docs) 

    ids, total_hurt, total_dead = set(), 0, 0 
    stats = dict((x, {}) for x in self.stats_columns) 
    stats['month'] = {} 
    for d in docs: 
     print('get', d) 
     if d['id'] in ids: 
      continue 
     else: 
      ids.add(d['id']) 
     for s in self.stats_columns: 
      if s in self.bool_columns: 
       key = u'Sí' if d[s] else 'No' 
      else: 
       key = d[s] 
      number = stats[s].get(key, 0) + 1 
      stats[s][key] = number 

     month_key = d['timestamp'].strftime('%b') 
     month_summary = stats['month'].get(month_key, {'hurt': 0, 'dead': 0}) 
     month_summary['hurt'] += d['total_hurt'] 
     month_summary['dead'] += d['total_dead'] 
     stats['month'][month_key] = month_summary 

     total_hurt += d['total_hurt'] 
     total_dead += d['total_dead'] 
    return { 
     'incidents': len(ids), 
     'involved': docs.count(), 
     'affected': total_hurt + total_dead, 
     'hurt': total_hurt, 
     'dead': total_dead, 
     'stats': stats 
    } 

テストセットアップ:

@classmethod 
def setUpClass(cls): 
    app.testing = True 
    cls.app = app.test_client() 
    cls.url = '/incidents' 
    cls.url_with_key = '/incidents?key=testKeyHash' 
    api.add_resource(_TestAll, cls.url) 

試験:

def test_get(self): 
    with patch('__main__._TestAll.collection.find') as search: 
     answer = [] 
     for i in range(3): 
      answer.append({ 
       'id': i, 
       'bool1': True, 'bool2': False, 
       'string1': 'test', 'string2': 'test', 
       'int1': 1, 'int2': 2, 
       'text1': 'test', 'text2': 'test', 
       'timestamp': datetime.now(), 'total_hurt': 1, 'total_dead': 0}) 
     search.__iter__.return_value = answer 
     search.return_value.count.return_value = len(answer) 
     response = self.app.get(self.url_with_key) 
     data = json.loads(response.data.decode()) 
     for i in search: 
      print('test', i) 
     print(data) 
     self.assertEqual(_TestAll.collection.find.call_count, 1) 
     self.assertIn('stats', data) 
     for s in _TestAll.stats_columns: 
      self.assertIn(s, data['stats']) 

ターミナル出力:リソースが反復可能を通じて適切にループをしませんが、テストができない理由

<MagicMock name='find()' id='4423760080'> 
('test', {'timestamp': datetime.datetime(2017, 5, 25, 13, 3, 9, 255912), 'text2': 'test', 'text1': 'test', 'int1': 1, 'int2': 2, 'id': 0, 'bool1': True, 'bool2': False, 'total_hurt': 1, 'total_dead': 0, 'string2': 'test', 'string1': 'test'}) 
('test', {'timestamp': datetime.datetime(2017, 5, 25, 13, 3, 9, 255923), 'text2': 'test', 'text1': 'test', 'int1': 1, 'int2': 2, 'id': 1, 'bool1': True, 'bool2': False, 'total_hurt': 1, 'total_dead': 0, 'string2': 'test', 'string1': 'test'}) 
('test', {'timestamp': datetime.datetime(2017, 5, 25, 13, 3, 9, 255928), 'text2': 'test', 'text1': 'test', 'int1': 1, 'int2': 2, 'id': 2, 'bool1': True, 'bool2': False, 'total_hurt': 1, 'total_dead': 0, 'string2': 'test', 'string1': 'test'}) 
{u'stats': {u'bool1': {}, u'int1': {}, u'month': {}}, u'involved': 3, u'dead': 0, u'hurt': 0, u'incidents': 0, u'affected': 0} 

は、私は理解していません。どんな助けもありがとうございます。 __iter__値を設定する場合

+0

私はあなたの質問を理解していません。私はあなたの問題を再現できません: 'x = MagicMock(); x .__ iter __。return_value = [1] 'は私にとってはうまくいきます。' for y:x:print(y) 'は' 1'を返します。問題を再現するために使用できる**完全な**例を提供してください。その間に問題が発生している可能性があります。 – Bakuriu

+0

@バクリュウクラスと設定方法を追加しました。私は他のテストをしていますが、私はそれらをコメントアウトしているので問題は解決しないので、それらは必要ありません。引数を渡していないので、search_doc()は空のdictを返します。他には何が関係していると思いますか? – gamda

答えて

0

、ラインが

search.__iter__.return_value = answer 

おかげで私は考慮にfilter()が呼び出し可能だったという事実を取ることはありませんでした。私がしようとしていたものを達成するための正しい方法は次のとおりです。

search.return_value.__iter__.return_value = answer 

searchモックが呼び出されていたので、新しいMagicMockが明らか__iter__プロパティセットを持っていなかった、返されました。リソースのget()とテスト機能が異なるモックにアクセスしていたため、そのうちの1つでしか機能しませんでした。

私が見つけたのは、テストメソッドの中にモックを印刷し、別のモックIDを取得することでした。

関連する問題