英文:
In Pytest, Is there a way to "mock" or prevent something from happening while collecting test?
问题
所以假设允许:
```python
# services/foo.py
from apps.bar import BarClass
static_foos = BarClass().get_statics()
class FooService():
....
和测试代码如下:
# tests/test_foo.py
from services.foo import FooService
def test_foo_something():
assert FooService.something() == True
在这里,当pytest收集测试时,它似乎在我的任何尝试在conftest.py
中模拟或阻止访问之前执行了BarClass.get_statics()
。
更具体地说,假设get_statics()
在其中有一些requests.get
,pytest中阻止网络的典型方法,即模拟socket.socket
,并不起作用。
据我所知,在测试被收集之前执行某些操作的唯一方法是在conftest.py
中使用pytest_configure
,但是据我所知,它不允许我进行模拟,这让我现在完全失去了希望(而且由于各种原因,我实际上也无法真正更改test_something
的内容)。
在这种情况下有可能的解决方案吗?
<details>
<summary>英文:</summary>
So assume the allowing :
services/foo.py
from apps.bar import BarClass
static_foos = BarClass().get_statics()
class FooService() :
....
and test code looking like :
tests/test_foo.py
from services.foo import FooService
def test_foo_something() :
assert FooService.something() == True
So here, when the pytest collects the test, it seems like it executes `BarClass.get_statics()` even before any of my attempts to mock or block access in `conftest.py` to kick in.
To be more specific, assuming `get_statics()` has some `requests.get` in it, a typical way of blocking network in pytest, which is mocking `socket.socket`, is not working.
From my knowledge, the only way to do something before tests get collected is to use `pytest_configure` in `conftest.py`, but also AFAIK it doesn't allow me to mock meaning that I'm just completely losing hope right now (Also it's not like I can really change the content of `test_something` for various reasons).
Is there any possible solution in this case?
</details>
# 答案1
**得分**: 2
```python
您可以在测试函数内部导入`services.foo`模块,*在*您对`requests.get`进行monkey-patch之后:
import requests
# 在这里定义您的MockResponse类
def test_foo_something(monkeypatch):
def mock_get(*args, **kwargs):
return MockResponse()
monkeypatch.setattr(requests, "get", mock_get)
from services.foo import FooService
assert FooService.something() == True
英文:
You can import the services.foo
module within the test function instead, after you monkey-patch requests.get
:
import requests
# define your MockResponse class here
def test_foo_something(monkeypatch):
def mock_get(*args, **kwargs):
return MockResponse()
monkeypatch.setattr(requests, "get", mock_get)
from services.foo import FooService
assert FooService.something() == True
答案2
得分: 2
您可以在导入`FooService`之前,从`apps.bar`中导入`BarClass`并模拟`get_statics`。例如:
from apps.bar import BarClass
def do_nothing(*args, **kwargs):
pass
BarClass.get_statics = do_nothing
from services.foo import FooService
def test_foo_something():
assert FooService.something() == True
但是我认为最好在`services.foo`中添加一些初始化函数,并在需要时调用它。类似于:
from apps.bar import BarClass
static_foos = None
def init():
static_foos = BarClass().get_statics()
class FooService():
...
<details>
<summary>英文:</summary>
You can import `BarClass` from `apps.bar` right before importing `FooService` and mock the `get_statics`. For example:
from apps.bar import BarClass
def do_nothing(*args, **kwargs):
pass
BarClass.get_statics = do_nothing
from services.foo import FooService
def test_foo_something() :
assert FooService.something() == True
However I think it would be better to add some initializing function to `services.foo` and call it when its needed. Something like:
from apps.bar import BarClass
static_foos = None
def init():
static_foos = BarClass().get_statics()
class FooService():
...
</details>
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论