简体   繁体   中英

set return_value of function

I have a class:

class AccountBusiness:
    def save(self, account) -> Account:
        if not account.account_number_is_valid():
            return False

        return True

and a test as:

@mock.patch.object(AccountBusiness, 'save')
def test_can_save_valid_account(self, mock_save):

    mock_account = mock.create_autospec(Account)
    mock_account.account_number_is_valid.return_value = False

    account_business = AccountBusiness()
    result = account_business.save(mock_account)
    self.assertEqual(result.return_value, True)

but it shows an exception like:

AssertionError: <MagicMock name='save()()' id='48830448'> != True

I want to set the return value of account.account_number_is_valid() to False and run the test.

You are using a patch object on the instance method you are looking to test. However, you are looking to test the logic inside the save method. So mocking that out will not test any of the logic inside that method. So, the output you are actually getting here:

AssertionError: <MagicMock name='save()()' id='48830448'> != True

Should be the first hint that something is not right. Your save method is coming back as a MagicMock . You don't want this. What you actually want to do is only mock the Account class, and go accordingly from there. So, your patching here:

@mock.patch.object(AccountBusiness, 'save')

should actually only be:

@mock.patch('path.to.AccountBusiness.Account', return_value=Mock(), autospec=True)

The path.to.AccountBusiness.Account is the location of the Account class with respect to the AccountBusiness class.

So, with that patching, then the return_value of calling Account will now be your mock object that you can use for your account_number_is_valid . So, the code will actually look like this:

class MyTest(unittest.TestCase):
    def setUp(self):
        self.account_business = AccountBusiness()

    @mock.patch('path.to.AccountBusiness.Account', return_value=Mock(), autospec=True)
    def test_can_save_valid_account(self, mock_account):
        mock_account_obj = mock_account.return_value
        mock_account_obj.account_number_is_valid.return_value = False

        self.assertFalse(self.account_business.save(mock_account_obj))

Also, pay close attention to the assertion at the end. It was changed to make use of the available assertFalse . Also, look over your own logic, as returning False for account_number_is_valid will actually return False in your save method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM