Search code examples
pythondjango-tests

Assertion error on a unit Django TestCase


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

Solution

  • 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,
                }
            )