Comments (3)
Hi @baudren!
I can reproduce the problem, thanks for the detailed explanation.
I checked that the mocker
fixture is calling mock.patch.object
at the appropriate places, so that seems fine.
I dug down into the source code for unittest.mock
and noticed that the line that actually installs the mock into the target object sometimes fail:
# contents of mock.py:1239
setattr(self.target, self.attribute, new_attr)
In the first mocker.patch.object
call from your example, this line is executed and correctly replaces QMessage.question
staticmethod
by a new MagicMock
instance. The second time this code is executed it sometimes fails to replace the existing MagicMock
instance by the new one, which can be verified by adding print(getattr(self.target, self.attribute))
right after it.
Changing your code slightly to add another level of indirection, like this:
class Simple(QFrame):
def query(self, notebook):
reply = self._question(notebook, self)
...
@staticmethod
def _question(notebook, parent):
return QMessageBox.question(
parent, 'Message', 'Deleting %s, are you sure?' % notebook,
QMessageBox.Yes | QMessageBox.No, QMessageBox.No)
def test_Qt(qtbot, mocker):
...
mocker.patch.object(simple, '_question',
return_value=QMessageBox.No))
Seems to fix the problem. My bet is that PySide
's bindings might be at fault here when one tries to change an staticmethod
attribute of a class.
Having said all that, an easy workaround is for you to reuse the mocked object:
def test_Qt(qtbot, mocker):
simple = Simple()
qtbot.addWidget(simple)
question = mocker.patch.object(QMessageBox, 'question',
return_value=QMessageBox.No)
simple.query('toto')
assert simple.answer == 'no'
question.return_value = QMessageBox.Yes
simple.query('toto')
assert simple.answer == 'yes'
Answering your questions:
Is it somehow forbidden to use two mock.patch.object statements in a row, without doing some sort of cleaning?
Shouldn't be necessary, but if you must you can use mocker.stopall()
.
And that it is pure luck that this works under 2.7?
No, it seems a consistent failure.
It seemed to me that the original mock module uses a Python
with ...: syntax, probably for house cleaning. There is no such thing in this
module, right?
No, there isn't... if you want to use a with
statement, you can use mock
directly. This was the motivation for changing the fixture name to mocker
, so you can use both in your tests if needed.
Or is it something due to the fact that now mock is integrated in py.test, since Python 3.3?
Don't think so, I believe it is the same source code. (I believe you meant Python above, of course 😁)
Thanks for the detailed explanation and bug report!
Cheers, 🍻
from pytest-mock.
Thanks, one more time, for the detailed explanation. I will go along the route of reusing the object - I should have thought about that myself. So you would say it is rather a problem directly with PySide, not with mock?
Best,
from pytest-mock.
Seems like it, this test fails for me in Python 3, but works in Python 2:
def test_foo():
for i in range(10):
QtGui.QMessageBox.question = i
assert QtGui.QMessageBox.question == i
Cheers!
from pytest-mock.
Related Issues (20)
- 6 tests fail HOT 1
- mocker.patch does not change return value HOT 3
- missing 1 required positional argument: 'mocker' HOT 3
- assert_called_once_with calls __eq__ multiple times HOT 3
- sdist is missing tox.ini HOT 1
- Spying on pydantic objects HOT 1
- Changelog broken HOT 2
- Mock method don't work when test from other file fail HOT 4
- async_stub doesn't need to be awaited HOT 1
- mocker.stub() is a coroutine function HOT 1
- feature request: fail on improper use of mock.side_effect HOT 2
- Record multiple calls to spy HOT 2
- How to patch return_value attribute? HOT 2
- The documentation should be clearer about not supporting context managers HOT 1
- Not sure why this is not working HOT 3
- `resetall` does not work when using `create_autospec` HOT 2
- Behavior of spy on class attributes HOT 3
- Call args/kwargs stored in a Spy can be overwritten without intention HOT 1
- test_failure_message_with_no_name fails with 3.11.7/3.12.1 HOT 1
- Failing tests for python 3.12 HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from pytest-mock.