Reputation: 193
While testing the create_response
method, I cannot seem to mock the return value of the get_external_response
method.
/foo/response
from abc import ABCMeta, abstractmethod
def create_response(url, type):
query = create_query(url, type)
external_response = get_external_response(query) <-- what I want to mock
return external_response
def create_query(url, type):
cc = MyFactory
return cc.get_concrete_class(url, type)
def get_external_response(cc):
return cc.make_query()
class MyAbstractClass(metaclass=ABCMeta):
def __init__(self, url, type):
self.url = url
self.type = type
self.query = self.make_query()
@abstractmethod
def make_query(self):
pass
class MyFactory:
@staticmethod
def get_concrete_class(url, type):
if type == 'A':
return MyClass(url, type)
else:
print("not valid type")
class MyClass(MyAbstractClass):
def __init__(self, url, type):
super().__init__(url, type)
def make_query(self):
return self.url + self.type
if __name__ == '__main__':
result = create_response('www.stackoverflow.com', 'A')
print(result)
If I run the above, I get the expected www.stackoverflow.comA
.
But if try to mock the return value of get_external_response
, it does not seem to do anything: it still returns www.stackoverflow.comA
and the assertion below fails.
/foo/test_response
from foo.response import create_response
import pytest
from unittest import mock
def test_create_response():
mock_external_response = mock.Mock()
mock_external_response.create_flask_response.return_value = 'www'
result = create_response('www.stackoverflow.com', 'A')
assert result == 'www'
I do not understand why the return value is not set since when the create_response
is called, it will eventually reach the point of calling the create_flask_response
which, if I am not mistaken, should return www
given that I have mocked it.
Can someone explain what I am doing wrong?
Upvotes: 7
Views: 12439
Reputation: 424
I noticed that you are creating a Mock object inside of a function, but are not actually using the Mock. It looks like you need to patch the function where it is used to use the Mock.
/foo/test_response
@mock.patch('foo.response.get_external_response')
def test_create_response(mock_get_external_reponse):
mock_get_external_response.return_value = 'www' # This is a Mock object, but will be used as a patch over the actual function where it is used
result = create_response('www.stackoverflow.com', 'A')
assert result == 'www'
Quick links to relevant documentation sections for convenience:
Intro to mocking and patching: https://docs.python.org/3/library/unittest.mock.html#quick-guide
Patch specifically here: https://docs.python.org/3/library/unittest.mock.html#unittest.mock.patch
Upvotes: 4