I created a unit test for my Question.save()
method in my webapp and when I run python manage.py test
I get an Assertion error as follows described below?
Here is my part of test.py
:
def test_elasticsearch_upsert_on_save(self, ElasticsearchMock):
user = get_user_model().objects.create_user(
username = 'unittest',
password='unittest',
)
question_title = 'Unit test'
question_body = 'some long text'
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_INDEX,
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,
}
)
part of models.py:
def as_elasticsearch_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,
}
def save(self, force_insert=False, force_update=False, using=None, update_fields=None):
super().save(force_insert=force_insert,
force_update=force_update,
using=using,
update_fields=update_fields)
elasticsearch.upsert(self)
I expect the test to pass but I get the following error:
FAIL: test_elasticsearch_upsert_on_save (qanda.tests.QuestionSaveTestCase)
----------------------------------------------------------------------
Traceback (most recent call last):
File "c:\program files (x86)\python37-32\Lib\unittest\mock.py", line 1204, in patched
return func(*args, **keywargs)
File "C:\Users\tafapc1\answerly\django\qanda\tests.py", line 48, in test_elasticsearch_upsert_on_save
},'doc_as_upsert': True,
File "c:\program files (x86)\python37-32\Lib\unittest\mock.py", line 840, in assert_called_once_with
return self.assert_called_with(*args, **kwargs)
File "c:\program files (x86)\python37-32\Lib\unittest\mock.py", line 829, in assert_called_with
raise AssertionError(_error_message()) from cause
AssertionError: Expected call: update('answerly', body={'doc': {'_type': 'doc', 'text': 'Unit test\nsome long t
ext', 'question_body': 'some long text', 'title': 'Unit test', 'id': 1, 'created': datetime.datetime(2019, 9, 1
1, 19, 38, 37, 498420, tzinfo=<UTC>)}, 'doc_as_upsert': True}, id=1)
Actual call: update('answerly', 'doc', body={'doc': {'_type': 'doc', 'text': 'Unit test\nsome long text', 'ques
tion_body': 'some long text', 'title': 'Unit test', 'id': 1, 'created': datetime.datetime(2019, 9, 11, 19, 38,
37, 498420, tzinfo=<UTC>)}, 'doc_as_upsert': True}, id=1)
----------------------------------------------------------------------
Ran 1 test in 1.420s
FAILED (failures=1)
Destroying test database for alias 'default'...
If you put the expected and the actual call below each other, you can see that they are actually different, so it makes sense that your test fails.
expected=update('answerly', body={'doc': {'_type': 'doc', 'text': 'Unit test\nsome long text', 'question_body': 'some long text', 'title': 'Unit test', 'id': 1, 'created': datetime.datetime(2019, 9, 11, 19, 38, 37, 498420, tzinfo=)}, 'doc_as_upsert': True}, id=1)
actual= update('answerly', 'doc', body={'doc': {'_type': 'doc', 'text': 'Unit test\nsome long text', 'question_body': 'some long text', 'title': 'Unit test', 'id': 1, 'created': datetime.datetime(2019, 9, 11, 19, 38, 37, 498420, tzinfo=)}, 'doc_as_upsert': True}, id=1)
Passing doc
as the second argument should fix your issue:
mock_client.update.assert_called_once_with(
settings.ES_INDEX,
'doc', # Added
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,
}
)