0

My test should with reason succeed as I'm giving a return value with mocker.return_value, which should give customers a value so the function call ends up in the else statement "Customer found". But it does not, from what I can tell the return value is not being mocked correctly, but why?

Mock:

from datachecker import DataChecker
from unittest import mock

@mock.patch.object(DataChecker, "execute_db")
def test_find_customer_true(mocker):
    mocker.return_value = 1
    assert DataChecker.find_customer(mocker, 1) == True

Class:

import sqlite3
from customer import Customer

class DataChecker:
   def __init__(self):
        self.conn = sqlite3.connect('pos.db')
        self.cursor = self.conn.cursor()

    def find_customer(self, customerID):
        query = "SELECT * FROM Customers WHERE ID == ?;"
        customers = self.execute_db(query, customerID, True)
        print(customers)
        
        if len(customers) == 0:
            print("Customer with given ID not found in DB")
            return False
        else:
            print("Customer found")
            return True

    def execute_db(self, query, params=None, fetch_one=False):
        if params:
            self.cursor.execute(query, [params])
            self.conn.commit()
        else:
            self.cursor.execute(query)
            self.conn.commit()
        if fetch_one:
            return self.cursor.fetchone()
        else:
            return self.cursor.fetchall()

Error:

=============================================================================================== FAILURES ================================================================================================
________________________________________________________________________________________ test_find_customer_true ________________________________________________________________________________________

mocker = <MagicMock name='execute_db' id='139976570824072'>

    @mock.patch.object(DataChecker, "execute_db")
    def test_find_customer_true(mocker):
        mocker.return_value = "hej"
>       assert DataChecker.find_customer(mocker, 1) == True
E    AssertionError: assert False == True
E     +  where False = <function DataChecker.find_customer at 0x7f4ed5e26598>(<MagicMock name='execute_db' id='139976570824072'>, 1)
E     +    where <function DataChecker.find_customer at 0x7f4ed5e26598> = DataChecker.find_customer

../lab2/tests/test_datachecker.py:45: AssertionError
----------------------------------------------------------------------------------------- Captured stdout call ------------------------------------------------------------------------------------------
<MagicMock name='execute_db.execute_db()' id='139976570473832'>
Customer with given ID not found in DB
======================================================================================== short test summary info ========================================================================================
FAILED tests/test_datachecker.py::test_find_customer_true - AssertionError: assert False == True

print(customers) gives: <MagicMock name='execute_db.execute_db()' id='139976570473832'>

To me it looks like there's something wrong here.. execute.db.execute_db(). According to my logic this print should give: 1?

octavemirbeau
  • 481
  • 6
  • 19
  • As I asked on your other post (https://stackoverflow.com/questions/66978311/mock-patch-gives-attributeerror) -- how is your object constructed? You have instance methods that reference attributes of `self` that are never initialized. – Samwise Apr 07 '21 at 02:36
  • Please see updated post – octavemirbeau Apr 07 '21 at 02:38

1 Answers1

2

It is not necessary to patch anything for this test. Since you're calling instance methods directly, you can simply pass a mock in as the self parameter.

from datachecker import DataChecker
from unittest.mock import Mock

def test_find_customer_true(mocker):
    mock_datachecker = Mock()
    mock_datachecker.execute_db.return_value = [1]
    assert DataChecker.find_customer(mock_datachecker, 1) == True
Samwise
  • 68,105
  • 3
  • 30
  • 44