Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Is it possible to mock an object globally for all notebooks, eg with conftest.py? #163

Open
ca-scribner opened this issue Jan 7, 2021 · 1 comment

Comments

@ca-scribner
Copy link

I have a suite of example notebooks that I wish to use as tests. Many use a python package to connect to a server, but when testing the syntax for making that connection is different. For example, in general the notebooks invoke Client() and because they're in the prod environment the connection requires no additional information, but the tests are run from a different runner which needs something like Client(additional_credentials).

Client is from an external library I cannot change and does not provide a good way to override the defaults from environment variables, etc. My plan was to mock the Client() during testing by using a session-scoped, autouse=True fixture in a conftest.py to inject the extra information into Client() calls. This works for regular pytests (.py files), but the notebooks evaluated by nbval do not have their Client() mocked over.

Schematic example:

client.py

class Client():
  def __init__(self, creds):
    self.x = creds

conftest.py

class ModifedClient():
  def __init__(self, *args, **kwargs):
    self.x = "some other creds"

@pytest.fixture(scope="session", autouse=True)
def patch_over_client(request):
  patched = mock.patch('client.Client', side_effect=ModifiedClient)
  active_mock = patched.start()
  def unpatch():
    patched.stop()
  request.addfinalizer(unpatch)

calling_notebook.ipynb

# (pretend these are cells)
from client import Client
c = Client()
assert c.x == "some other creds"

Is there a way to make this work or a better pattern achieve the same result?

@takluyver
Copy link
Member

I don't think there's any great way to do this, because the notebook code is running in a separate process - nbval launches a Jupyter kernel, and sends the cells to that. It might be possible to hack something with .pth files or a sitecustomize.py (see the site module docs) to make code run when the kernel is starting up. But that definitely wouldn't be elegant, and I don't know quite how to ensure it's cleaned up at the right time.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants