Search code examples
python-3.xunit-testingtestingmockingdjango-tests

Mock function outside package


I'm developing a Django software with different apps on it. I'm testing some views and I want to mock the return of a function inside these views.

For example I have this view (located at apps.policies.views):

def upload_policy_document(request):

    # code fragment avoid

    # save document ot ipfs
    response_data = save_to_ipfs(app_name=app_name,
                                 process_instance=process_instance,
                                 file=policy_document)
    # more code avoided

    return JsonResponse(data=response_data)

The function save_to_ipfs is located at apps.utils.ipfs_storage and is the function I want to mock to return a fixed value without connecting to the IPFS.

I have some tests of this view located at apps.policies.tests.test_views. As a test example I have:

class UpdatePolicyDocumentMockCase(SimpleTestCase):

    IPFS_JSON_MOCK = {"Hash": "mockhash"}

    def setUp(self):
        # some setup before tests

    @patch('apps.utils.ipfs_storage.save_to_ipfs')
    def some_test(self, mock_method):

        mock_method.return_value = self.IPFS_JSON_MOCK
        self.assertEqual(save_to_ipfs("", "", ""), self.IPFS_JSON_MOCK)

The problem is that the mock doesn't work and it returns empty when the reurn must be the content of self.IPFS_JSON_MOCK.

I hope I've explained correctly, thanks in advance!


Solution

  • I have learned my lesson here:

    "If you want to run a function whenever a mock is called, that's side_effect, not return_value"

    Outside of TestClass, add a func:

    local_save_to_ipfs():
       IPFS_JSON_MOCK = {"Hash": "mockhash"}
       return IPFS_JSON_MOCK
    

    Inside UpdatePolicyDocumentMockCase, change to this, it should work.

    it should be just a func name without ()

    mock_method.side_effect = local_save_to_ipfs()
    

    this is the right way without the Round brackets or parentheses

    mock_method.side_effect = local_save_to_ipfs
    

    Here is a link to an example:

    https://fgimian.github.io/blog/2014/04/10/using-the-python-mock-library-to-fake-regular-functions-during-tests/