1

I am currently using asgi_correlation_id python package in my FastApi project. This package exposes a ContextVar called correlation_id.

The usage is simple:

from asgi_correlation_id.context import correlation_id

id = correlation_id.get()

Now, it is this particular line that I want to monkeypatch for my pytests.

Here is what all I have tried whole day:

#try1
def mock_correlation_id():
    return 123456

monkeypatch.setattr(correlation_id, "get", mock_correlation_id)

#try2
def mock_correlation_id():
    return None

monkeypatch.setattr("asgi_correlation_id.context.correlation_id.get", mock_correlation_id)

#try3
def mock_correlation_id():
    return mock_id.get()

mock_id = ContextVar("mock_id", default=None)
monkeypatch.setattr("asgi_correlation_id.context.correlation_id.get", mock_correlation_id)

#try4
monkeypatch.setattr("asgi_correlation_id.context.correlation_id.get", lambda: None)

#try5
monkeypatch.setattr("asgi_correlation_id.context.correlation_id.get", lambda: 1234567)

But every single time, I am greeted with the same error:

Attribute error: 'ContextVar' object attribute 'get' is read-only.

/pythonpath/_pytest/monkeypatch.py:360: Attribute Error

I am surprised, I couldn't find any implementation of mocking contextvars on the net. Can anyone help me out on this?

Laurent
  • 12,287
  • 7
  • 21
  • 37
raghavsikaria
  • 867
  • 17
  • 30
  • is the line `id = correlation_id.get()` at module level, or inside some function/method? if it is at module level, you have to patch it directly, of course – jsbueno Jun 03 '22 at 16:43

1 Answers1

1

Would using the set() and reset() methods work for you?

from contextvars import ContextVar

c = ContextVar("my_var")
c.set("old_val")


async def test_var():
    assert c.get() == "old_val"
    token = c.set("new_val")
    assert c.get() == "new_val"
    c.reset(token)
    assert c.get() == "old_val"