我有一个返回以下错误的测试用例。
跟踪
Traceback (most recent call last):
File "/usr/lib/python3.7/unittest/mock.py", line 1255, in patched
return func(*args, **keywargs)
File "/dir/to/project/Anwser/qanda/tests.py", line 29, in test_elasticsearch_upsert_on_save
q.save()
File "/dir/to/project/Anwser/qanda/models.py", line 40, in save
elasticsearch.upsert(self)
File "/dir/to/project/Anwser/qanda/service/elasticsearch.py", line 54, in upsert
doc_type = question_dict['_type']
TypeError: 'method' object is not subscriptable
这是elasticsearch.py
内的函数
def upsert(question_model):
client = get_client()
question_dict = question_model.as_elastic_search_dict
doc_type = question_dict['_type']
del question_dict['_id']
del question_dict['_type']
response = client.update(
settings.ES_IDENX,
question_dict,
id=question_model.id,
body={
'doc': doc_type,
'doc_as_upsert': True,
}
)
return response
当我阅读了有关类似问题的其他文章时,我得出的结论是,问题取决于调用该函数的对象的 __ getItem(self)__ 。 由于该函数应该返回字典,因此它返回一个方法。
这是模型内部的功能。
def as_elastic_search_dict(self):
return {
'_id': self.id,
'_type': 'doc',
'text': '{}\n{}'.format(self.title, self.question),
'question_body': self.question,
'title': self.title,
'id': self.id,
'created': self.created,
}
TestCase:
class QuestionSaveTestCase(TestCase):
"""
Testing Question.save()
"""
@patch('qanda.service.elasticsearch.Elasticsearch')
def test_elasticsearch_upsert_on_save(self, ElasticSearchMock):
user = User.objects.create(
username='unittest',
password='unittest'
)
question_title = 'Unit test'
question_body = 'Some unit test'
q = Question(title=question_title,
question=question_body,
user=user)
q.save()
self.assertIsNotNone(q.id)
self.assertTrue(ElasticSearchMock.called)
mock_client = ElasticSearchMock.return_value
mock_client.update.assert_called_once_with(
settings.ES_IDENX,
id=q.id,
body={
'doc': {
'_type': 'doc',
'text': '{}\n{}'.format(question_title, question_body),
'question_body': question_body,
'title': question_title,
'id': q.id,
'created': q.created,
},
'doc_as_upsert': True,
}
)
可用于解决此问题的所有可能用例是什么?如果我的理解是正确的,那么我应该重写 __ getItem(self)__ 以返回字典。如果正确,我应该如何实现 __ getItem(self)__ ,并且将其配置为返回字典,它将对对象的生命周期产生总体影响?
答案 0 :(得分:0)
您需要执行该方法,方法名称后缺少括号,将question_model.as_elastic_search_dict
更改为question_model.as_elastic_search_dict()
。
所以您的功能将是:
def upsert(question_model):
client = get_client()
question_dict = question_model.as_elastic_search_dict()
doc_type = question_dict['_type']
del question_dict['_id']
del question_dict['_type']
response = client.update(
settings.ES_IDENX,
question_dict,
id=question_model.id,
body={
'doc': doc_type,
'doc_as_upsert': True,
}
)
return response