has207 / flexmock Goto Github PK
View Code? Open in Web Editor NEWNow hosted at:
Home Page: https://github.com/bkabrda/flexmock
License: Other
Now hosted at:
Home Page: https://github.com/bkabrda/flexmock
License: Other
flexmock(obj).should_call("method").with_args(1).once
flexmock(obj).should_call("method").with_args(2).once
Ends up calling the method a lot more than once, possibly due to an issue with saving original_method
According to http://has207.github.com/flexmock/user-guide.html#expectation-matching, to match exactly no arguments, one has to write:
flexmock(foo).should_receive('method_bar').with_args()
either by calling new_instances multiple times or using multiple return values
e.g. flexmock(foo).should_receive('method.that.violates.law.of.demeter')
should_call could just pass the original method using replace_with instead of having a special case and_execute (which probably isn't used other than by should_call anyway)
in other words:
flexmock(foo).should_call('blah').and_raise(Exception)
should match any Exception and not fail when the exception value doesn't match
Record method calls, arguments, return values and ordering, and verify that they've been made the same way again.
Something along the lines of:
with flexmock(some_object) as recorder:
known_good_algorithm(recorder)
new_algorithm(recorder)
--or more explicitly--
with flexmock(some_object) as recorder:
recorder.method1(arg, arg)
recorder.method2(arg)
new_algorithm(recorder)
The enter method would set up record mode and the exit method would clean up record mode and put the object back in normal mode.
On < 2.6 we can do:
recorder = flexmock(some_object)
recorder.record
known_good_algorithm(recorder)
recorder.replay
new_algorithm(recorder)
overriding return values only gets you so far, sometimes it's useful to replace the method with a custom function that does things based on provided arguments, maybe something like:
flexmock(foo).should_receive(method).replace_with(lambda x, y: y == 5)
Go to http://has207.github.com/flexmock/why.html and click on "next" or go to http://has207.github.com/flexmock/index.html#user-guide and click any of the items there.
Maybe there are more. But I found those two trying to access the doc.
probably need to write a nose plugin or something similar to properly call flemock teardown from nose tests that don't belong to a class inheriting from unittest.TestCase
Hi Herman,
after upgrading to master I get a false negative for one of my tests. I tracked this back to a call to hasattr(some_mock, 'some_attr') which always returns True, even if the attribute does not exist. This seems to be a regression because the test passed with earlier versions of flexmock.
I'll commit a failing test case (based on master this time ;-) ) for you to easily reproduce the issue.
Florian
similar to type matching but do the right thing when the arg/return value is a regex object
Ability to turn should_receive into should_call with an env variable to enable running same set of tests as unit tests or integration tests
flexmock.should_receive('foo', 'bar', 'baz')
instead of
flexmock.should_receive('foo.bar.baz')
(I'm not entirely convinced this is the right approach yet)
flexmock(foo).should_receive('bar').at_least.once.at_most.times(3)
i.e. stuff in the "with" statement
or any other top level method we assign
Hi!
First of all I have to say that I'm very impressed with flexmox. It's by far the most concise and readable python mock framework around. Great work!!
I'm having an issue when debugging tests with PyDev (and probably other debuggers will have the same problem). Debuggers tend to systematically inspect properties (among other objects) when hitting a breakpoint or similar. And even if they don't do this themselves, they'll let the user inspect those properties on demand.
Changing the state of an object when read-accessing it's properties is an "uncommon" practice. Most devs will find it hard to debug this as state will change "magically" and "unpredictably" without any hint to the user about what's going on in the background.
This problem is not limited to debuggers, of course, but potentially extends to all tools that inspect objects, potentially including nose plug-ins or even nose itself.
My favorite solution would be to turn properties like Expectation.once into functions. This would document the potential side-effect to the caller and would conform to widely accepted design practices. I think the additional () is acceptable from a readability pov.
I wouldn't even consider inspecting the stack trying to find out whether the property is called from within a test. This would be very hard to do properly (as can be seen with nose support - another bug will follow suite). Inspecting the stack badly breaks encapsulation and therefore the code will break in subtle ways when being changed or called in unforeseen ways.
Florian
probably won't work in older python versions
Something like:
power = flexmock(is_on=False)
radio = flexmock(Radio)
radio.should_receive('switch_on') # do something to tweak the state
radio.should_receive('select_channel').when(power.is_on)
radio.should_receive('adjust_volume').with(+5).when(power.is_on)
radio.should_receive('switch_off') # tweak the state again
e.g. time.time
According to http://has207.github.com/flexmock/user-guide.html#expectation-matching, to match exactly no arguments, one has to write:
flexmock(foo).should_receive('method_bar').with_args()
The following code however returns "True", even when the expectation is no arguments and arguments were given:
def _match_args(given_args, expected_args):
if (... expected_args == {'kargs': (), 'kwargs': {}}):
return True
Is this intended behavior? In this case I propose changing the documentation.
If I stub a mock's method by default in setUp, ordering expectations are no longer checked:
For example, the following passes:
def setUp(self):
self.testobj = flexmock()
self.testobj.should_receive('Add')
def testSomething(self):
self.testobj.should_receive('Add').with_args('bob').ordered.once
self.testobj.should_receive('Add').with_args('carl').ordered.once
self.testobj.Add('carl')
self.testobj.Add('bob')
to make sure automatic cleanup happens in doctests
Nose calls only the first of ('teardown', 'tearDown') and returns immediately after executing it. This means that if a flexmock test case implements tearDown() then it is never called.
Off of my head I can think of two potential solutions:
Check whether the test contains a tearDown() method and call it from flexmock's teardown() method.
(IMO slightly better): Adapt flexmock's method naming to the nomenclature used by the original test class. If there is a 'tearDown' method then monkey-patch 'tearDown', otherwise monkey-patch 'teardown'.
test runner integration should be even more dynamic than it is now and figure out the right integration mode based on the calling runner
NoseMock accesses the stack at a fixed point which doesn't work when it's being instantiated as a partial mock. The problem is deeper than that. Generally accessing the stack breaks encapsulation.
I'll submit a patch shortly that fixes the immediate problem. But it only fixes the problem partially because it still relies on flexmock being used directly from within the unit test class. This is a reasonable assumption but it will break if people delegate repeated tasks to some external helper methods/classes outside the test proper which happens quite frequently. So this restriction should at least be well documented.
I want to mock a class which has the method __iter__
to make the instances of this class iterable. But unfortunately, flexmock forbids mocking magic methods (those which begin and end with __
) like __iter__
(https://github.com/has207/flexmock/blob/0.6.8/flexmock.py#L338). Therefore, I cannot make my instance iterable as I want it.
Here's a python session to demonstrate my situation: http://paste.pocoo.org/show/319979/
It would be kind if there was a possibility to enable mocking special attributes. Maybe by giving the method should_receive
a keyword argument is_special_attribute
or something like that.
foo = flexmock()
foo['bar'] = 'baz'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.