So I am trying to test an api lookup with my mock data.
I am testing a method within transform.py that imports a module lookup
import lookup
col = lookup.ColFinder()
url = "xyz"
if col.is_present(url):
do this
lookup.py
import secdata
class ColFinder():
def is_present(url):
if url in secdata.CUSTOM_STUFF:
return secdata.CUSTOM_STUFF[url]
secdata.py
secdata.CUSTOM_STUFF=load("some_file")
I want to mock the JSON (file being loaded within secdata.CUSTOM_STUFF)
I have tried mocking using the unittest.mock with some custom config within tests/resources
CUSTOM_CONFIG = secdata.load(os.path.join(os.path.dirname(__file__),'/resources/custom_config.json'))
import mock
#mock.patch("transform.lookup.secdata.CUSTOM_STUFF" , return_value=CUSTOM_CONFIG)
def test_blah_blah(self, *_):
but this doesn't seem to load the file I am trying to reference. Please can someone help me mock this, point out what am I doing wrong.
Thank you in advance.
Related
In the following code, the request has the type of <class '_pytest.fixtures.SubRequest'>. I want to add type hint to the parameter request.
#pytest.fixture
def dlv_service(request: SubRequest): # How to import SubRequest?
print(type(request), request)
filepath = pathlib.Path(request.node.fspath.strpath)
f = filepath.with_name("file.json")
The following import doesn't work.
from pytest.fixtures import SubRequest
I've found one on the internet, hope this will help.
from _pytest.fixtures import SubRequest
I think it's worth trying, but not sure whether it could work, sorry.
For some applications, such as accessing the node property, you can import FixtureRequest, which is part of the public API and a superclass of SubRequest. See yourself:
from _pytest.fixtures import SubRequest
from pytest import FixtureRequest
issubclass(SubRequest, FixtureRequest)
hasattr(FixtureRequest, "node")
Applying this to your example:
from pathlib import Path
import pytest
from pytest import FixtureRequest
#pytest.fixture
def dlv_service(request: FixtureRequest) -> Path:
print(type(request), request)
filepath = Path(request.node.fspath.strpath)
return filepath.with_name("file.json")
Can you please help me out to figure what I did wrong? I have the following unit test for a python lambdas
class Tests(unittest.TestCase):
def setUp(self):
//some setup
#mock.patch('functions.tested_class.requests.get')
#mock.patch('functions.helper_class.get_auth_token')
def test_tested_class(self, mock_auth, mock_get):
mock_get.side_effect = [self.mock_response]
mock_auth.return_value = "some id token"
response = get_xml(self.event, None)
self.assertEqual(response['statusCode'], 200)
The problem is that when I run this code, I get the following error for get_auth_token:
Invalid URL '': No schema supplied. Perhaps you meant http://?
I debugged it, and it doesn't look like I patched it correctly. The Authorization helper file is in the same folder "functions" as the tested class.
EDIT:
In the tested_class I was importing get_auth_token like this:
from functions import helper_class
from functions.helper_class import get_auth_token
...
def get_xml(event, context):
...
response_token = get_auth_token()
After changing to this, it started to work fine
import functions.helper_class
...
def get_xml(event, context):
...
response_token = functions.helper_class.get_auth_token()
I still don't fully understand why though
In your first scenario
in tested_class.py, get_auth_token is imported
from functions.helper_class import get_auth_token
The patch should be exactly the get_auth_token at tested_class
#mock.patch('functions.tested_class.get_auth_token')
Second scenario
With the following usage
response_token = functions.helper_class.get_auth_token()
The only way to patch is this
#mock.patch('functions.helper_class.get_auth_token')
alternative
With import like this in tested_class
from functions import helper_class
helper_class.get_auth_token()
patch could be like this:
#mock.patch('functions.tested_class.helper_class.get_auth_token')
patch() works by (temporarily) changing the object that a name points to with another one. There can be many names pointing to any individual object, so for patching to work, you must ensure that you patch the name used by the system under test.
The basic principle is that you patch where an object is looked up, which is not necessarily the same place as where it is defined.
Python documentation has a very good example. where to patch
I have a project assigning 2 configs in my main __init__ file since they are used frequently throughout the project.
#__init__.py
from config import Config
config1 = Config('Email')
config2 = Config('Test')
My Config class within config.py has a method called content that I need to mock out on instances config1 and config2. The config does call out to a third party library to do an http request, so I need to return a json dictionary for the response to content.
In a validators function I have the following:
#validation.py
from parser import config1, config2
def validation(msg):
if "email" in config1.keys():
...
I'm not trying to mock out the tests but keep getting errors. I've tried various mock patch paths but none work.
My latest attempt is the following:
from mock import patch
from parser import validation
#patch('parser.Config')
def test_is_valid(mock_config):
mock_config.return_value.content = "Test"
assert validation.is_valid("email") == True
What am I doing wrong that my instances of Config (config1, and config2) are not correctly returning the .content values? Thanks
I am basically using magic mock and context manager to test my code, I was successfully able to mock my get_urls function, But I am having trouble mocking out my access_all_repos_pr(): function which contains data of PR newer than 7 days, can anyone help me out on how to mock that data.
Here is the test code for my get_urls():
import unittest
from mock import MagicMock, patch
from contextlib2 import ExitStack
from GithubAPIpackage.GithubAPI import get_urls
class Test_GithubApi(unittest.TestCase):
def test_get_urls_returns_valid_urls(self):
with ExitStack() as stack:
mock_get_urls = stack.enter_context(
patch("GithubAPIpackage.GithubAPI._fetch_url")
)
fake_data = {"current_user_repositories_url": "http://FAKEURL.com"}
mock_get_urls.return_value = fake_data
print(type(fake_data))
result = get_urls()
self.assertEqual(result, "http://FAKEURL.com")
I want to mock out the response for the function access_all_repo_pr, can anyone help me out in what I need to do exactly to create a mock for my access_all_repo_pr function. Do I need to refactor my code in some way? (relatively new to python)
what I am trying is:
class Test_GithubApi_newer_than_7_days(unittest.TestCase):
def test_access_all_repo_pr_returns_valid_response(self):
with ExitStack() as stack:
mock_access_all_repo_pr = stack.enter_context(
patch("GithubAPIpackage.GithubAPI._fetch_url")
)
fake_data = {"current_user_repositories_url": "http://myfakeurl.com"}
mock_access_all_repo_pr.return_value = fake_data
result = access_all_repo_pr()
self.assertEqual(result, "")
Since you are using requests under the hood, may I suggest using responses for your testing? Not trying to skirt the question, but in my experience, I have found this to be the path of least resistance when it comes to writing tests that deal with the requests module. The tests end up being a lot cleaner, safer, and easier to write.
I trying to understand how to manage module with __all. For example, I have following structured code:
main.py
|=> /database
|=> __init__.py
|=> engine (with variables engine, session, etc.)
now I want to be able to import session and engine instances directly from database module like:
from database import session
I tried to add line __all__ = ['session'] or __all__ = ['engine.session'] to __init__py but when I trying to do import I've got an exception AttributeError: 'modile' object has not attribute 'engine.session'.
Is there any way to achieve wanted behavior?
Listing names in __all__ does not, by itself, import items into a module. All it does is list names to import from that module if you used from database import * syntax.
Import session into database/__init__.py:
from .engine import session