I'm trying to patch dependencies with my errbot tests. The problem I'm having is how errbot imports modules. It is not static and breaks my patch decorators as I add tests or they test in a different order.
I have plugin called EDB (edb.py). Inside of edb.py I import pyedb with import pyedb
. This is located in my site-packages
.
I have my test file test_edb.py and I try to patch my test methods like this
pytest_plugins = ["errbot.backends.test"]
extra_plugin_dir = '.'
from unittest.mock import patch # noqa: E402
@patch('yapsy_loaded_plugin_EDB_1.pyedb', autospec=True)
def test_edb_testlist(pyedb_mock, testbot):
testbot.push_message('!edb testlist')
assert "Okay, let me get..." == testbot.pop_message()
assert "I don't see any..." == testbot.pop_message()
Errbot adds this yapsy_loaded_plugin_EDB_<xx>
path for module import but the xx depends on the order the test is run. This doesn't work, I need some static import path mypath.pyedb
.
I'm hoping there is a different way to approach this. Maybe I can change the how I import the module so it's not dependent on errbot imports?
Here is a link to Errbot testing for reference.
My solution feels a bit hacky but it works. If anyone has a more elegant solution please share. I'll accept my own answer after awhile if there are no additional responses.
So I've come across this before but I guess I still wasn't familiar enough with how patching works in Python with knowing where to patch. After reading the "Where to patch" documentation ( again :) ) I have a work-around given the dynamic imports with errbot.
An errbot project folder will look something
errbot-project/
├── data/
│ ├── ...
├── plugins/
│ ├── plugin1/
| ├── ...
| ├── plugin2/
| ├── ...
I noticed that when errbot runs both the project directory ../errbot-project
and all the plugin directories (e.g. ../errbot-project/plugins/plugin1
) are added to sys.path
.
So I added a package to my project directory and I import that in my plugins. I then can patch my dependencies reliably from that package. Again read the Where to Patch documentation for full explanation why. It looks something like this.
errbot-project/
├── data/
│ ├── ...
├── plugins/
│ ├── plugin1/
| ├── ...
| ├── plugin2/
| ├── ...
├── plugin_deps/
| ├── __init__.py
Where my ../errbot-project/plugin_deps/__init__.py
looks like
...
import dep1
import dep2
...
And then in my plugin I use
...
import plugin_deps as pdep
...
def method():
pdep.dep1.method()
...
# note, you cannot use
# from plugin_deps import dep1
# this changes 'where' python looks up the module and
# and 'breaks' your patch
And finally my test code looks like
@patch('plugin_deps.dep1', autospec=True)
def test_get_tl_tabulation(my_mock, testbot):
# test code here