Open GoogleCodeExporter opened 9 years ago
What would that actually do? (Why reuse mocks anyway - they're not expensive to
create?)
Original comment by fuzzyman
on 10 Jun 2010 at 9:51
not for reuse mocks, rather to get rid of repetitive mocking of the same
resource. That would be useful for older Python versions (with no class
decorators).
Original comment by kon...@gmail.com
on 10 Jun 2010 at 11:08
both tickets (this and #31) are for situations when every test method needs
common patching.
Also, for some reason, google doesn't let me mark it a en
enhancement/feature-request
Original comment by kon...@gmail.com
on 10 Jun 2010 at 11:12
I kind of see what you mean, but have trouble imagining how the code might
look. Perhaps you could explain to me what you think "setup_mocking" and
"teardown_mocking" should do. (Or even better write a patch - but an
explanation would be fine.)
Original comment by fuzzyman
on 10 Jun 2010 at 11:12
Original comment by fuzzyman
on 10 Jun 2010 at 11:18
Ah. So, mock.setup_mock('sys.stdin') would patch sys.stdin and return the mock
(presumably with some stored state so that teardown_mock can unpatch
automatically).
That sounds fine - although "setup_mock" isn't quite the right name as it is
more to do with patching. That sounds useful, but how would you ensure that the
unpatching is done on test failure? Is that just up to the user to ensure?
I'd definitely be open to a patch for this (with docs and tests of course) and
we can debate the names later...
Original comment by fuzzyman
on 10 Jun 2010 at 11:22
My use case is similar to one for class decorator: Say you have a an object
that hits the web on each instantiation. In order to make test reliable you
want to patch this behaviour, but there's ton of logic that you need to test,
so your @mock.patch() becomes painfully repetitive. Both tickets propose a
feature covering this use case. What I had in mind was to prepare series of
patches, store it in self._original_state and then restore in teardown. The
default setup/teardown behaviour would be used for basic test failure safety.
Original comment by kon...@gmail.com
on 10 Jun 2010 at 11:30
> I'd definitely be open to a patch for this
Great :)
I switched from preparing patches first to reporting issue first - when I
implemented unittest2.collector yesterday, I found out you did it two hours
before :)
Original comment by kon...@gmail.com
on 10 Jun 2010 at 11:56
Original comment by fuzzyman
on 12 Jun 2010 at 11:22
Here's the overview of the API that's going to get implemented
{{{
class TestSomething(unittest.TestCase):
def setUp(self):
self.patches = mock.patch.setup("sys.stdin", # you can pass a string. this would work like patch("sys.stdin")
mock.patch("sys.stdout"), # you can pass a patch decorator object
mock_stderr=mock.patch.object(sys, "stderr")) # you can pass patch.object decorator instance, but you need to give keyword argument for that if you want to access it
def testSomething(self):
self.patches["sys.stdin"]
self.patches["sys.stdout"]
self.patches["mock_stderr"]
def tearDown(self):
self.patches.unpatch()
}}}
Original comment by kon...@gmail.com
on 12 Jun 2010 at 11:27
I'm not sure I like "unpatch" as method name. How about "restore"?
The patches object returned by patch.setup could (should?) be a context
manager, so you can use it in a with statement and have "unpatch" (or
"restore") called automatically for you:
{{{
patches = patch.setup('sys.stdin', 'sys.stdout')
with patches:
...
}}}
Original comment by fuzzyman
on 12 Jun 2010 at 1:16
> I'm not sure I like "unpatch" as method name. How about "restore"?
I don't like it either. I thought about "restore", but it wouldn't make much
sense semantically: that would read "restore the patches" rather than "restore
the originals".
What about clean() or cleanup()?
Original comment by kon...@gmail.com
on 12 Jun 2010 at 1:53
I don't think "restore" implies "restore the patches", "cleanup" is fine - but
perhaps we should go with "teardown" to be symmetrical with "setup"? Finding a
nice symmetrical pair would be ideal. "setup" and "teardown" have their own
meaning in unit testing so it is perhaps not ideal to re-use them (?) - but
they're not too bad.
Original comment by fuzzyman
on 12 Jun 2010 at 2:45
Original comment by fuzzyman
on 13 Jun 2010 at 8:43
Actually unpatch and teardown are both fine as names.
Original comment by fuzzyman
on 15 Oct 2010 at 4:28
I use the following pattern:
class MyTest(TestCase):
def setUp(self):
self._metamock = patch('myapp.models.meta')
self.metamock = self._metamock.__enter__()
self.metamock.Session.query.return_value = []
def tearDown(self):
del self.metamock
self._metamock.__exit__()
On IRC fuzzyman suggested patch.setup and patch.teardown, which I like, it
makes it clear what it's meant for.
I also like the self.patches above, but would like an API for single mocks as
well like in my pattern above. Though that could also be done with a manual
assignment like self.metamock = self.patches["myapp.models.meta"]
Original comment by fschulz...@googlemail.com
on 15 Oct 2010 at 4:33
A work colleague asked for this today. Definitely something we should support.
Clean API still needs to be worked out.
I think I prefer adding the patches with a series of calls rather than one long
call doing multiple patches. Something along the lines of:
{{{
def setUp(self):
self.patches = mock.patcher()
self.patches.add(*args)
self.patches.add(*args)
}}}
The mocks could then be accessed by indexing self.patches, either positionally
or by name.
{{{
def tearDown(self):
self.patches.unpatch()
}}}
Original comment by fuzzyman
on 12 Nov 2010 at 12:52
My colleague would like add to return the mock to avoid *having* to index the
patcher.
Note that we would need patcher.add_object (and patcher.add_dict) as well.
Perhaps patcher.add_object and add_dict could require you to specify a name and
we could not provide indexing by position?
Original comment by fuzzyman
on 12 Nov 2010 at 1:20
Note that in the Hg repo (and will be in 0.7.0b4) patch objects now have start
/ stop methods. These are only aliases for __enter__ / __exit__ but make it a
bit prettier to use in this way. Calling start returns the mock (default
behaviour of __enter__ anyway). So you can do:
{{{
def setUp(self):
self.patch = patch('something.foo')
self.mock_foo = self.patch.start()
def tearDown(self):
self.patch.stop()
}}}
This works with patch, patch.object and patch.dict.
Original comment by fuzzyman
on 12 Nov 2010 at 2:07
Note that patch objects have start and stop methods in 0.7.0. A nice API for
multiple patches in setUp / tearDown would still be nice.
Original comment by fuzzyman
on 6 Dec 2010 at 11:17
Original comment by fuzzyman
on 28 May 2011 at 11:24
I've drafted an implementation of this here:
http://code.google.com/r/wolfgangschnerring-setupteardown/source/browse
If there is interest, I'll try to add to the documentation, too.
This is my first patch to `mock`, so any feedback is appreciated.
Original comment by wolfgang.schnerring
on 30 Nov 2011 at 5:01
I think the "patcher" looks pretty straight forward. I think there should be a
way to access the individual mocks, though. Otherwise you end up storing them
manually again, which kinda defeats the purpose of managing them together.
Maybe with a "name" attribute in the add_* methods and simple dict like access?
Original comment by florian....@gmx.net
on 9 Dec 2011 at 11:17
I agree with florian that *some* way of accessing the mocks after creation
would be useful.
Original comment by fuzzyman
on 29 Dec 2011 at 12:50
patcher.start() and patcher.stop() allow you to use patch in setUp and
tearDown. Perhaps a way of doing multiple patches in a single call would still
be useful?
Original comment by fuzzyman
on 14 Nov 2013 at 11:15
Original issue reported on code.google.com by
kon...@gmail.com
on 10 Jun 2010 at 9:49