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__
値を設定する場合
私はあなたの質問を理解していません。私はあなたの問題を再現できません: 'x = MagicMock(); x .__ iter __。return_value = [1] 'は私にとってはうまくいきます。' for y:x:print(y) 'は' 1'を返します。問題を再現するために使用できる**完全な**例を提供してください。その間に問題が発生している可能性があります。 – Bakuriu
@バクリュウクラスと設定方法を追加しました。私は他のテストをしていますが、私はそれらをコメントアウトしているので問題は解決しないので、それらは必要ありません。引数を渡していないので、search_doc()は空のdictを返します。他には何が関係していると思いますか? – gamda