Reputation: 1365
I have an object
class Obj:
def method1(self):
print 'method1'
def method2(self):
print 'method2'
def method3(self):
print 'method3'
and function
def do_something():
obj = Obj()
obj.method2()
obj.method1()
obj.method3()
And I want to write test which tests do_something and Obj object. How can I receive list of methods which was called on obj without replacing (mocking) and changing obj behavior?
Something like
['method2', 'method1', 'method3']
Upvotes: 1
Views: 718
Reputation: 49856
Use the trace
package. See docs: http://docs.python.org/2/library/trace.html
From the docs:
import sys
import trace
# create a Trace object, telling it what to ignore, and whether to
# do tracing or line-counting or both.
tracer = trace.Trace(
ignoredirs=[sys.prefix, sys.exec_prefix],
trace=0,
count=1)
# run the new command using the given tracer
tracer.run('main()')
# make a report, placing output in the current directory
r = tracer.results()
r.write_results(show_missing=True, coverdir=".")
Upvotes: 3
Reputation: 3131
You can create a generic Wrapper
class which will encapsulate your object and track changes to it.
class Obj:
def method1(self):
print 'method1'
def method2(self):
print 'method2'
def method3(self):
print 'method3'
class Wrapper:
def __init__(self, wrapped):
self.calls = []
self._wrapped = wrapped
def __getattr__(self, n):
self.calls.append(n)
return getattr(self._wrapped, n)
By redefining __getattr__
we cause all attribute accessing on the wrapper to retrieve the attribute in the wrapped object. With the above defined I can do the following:
>>> obj = Obj()
>>> x = Wrapper(obj)
>>> x.calls
[]
>>> x.method2()
method 2
>>> x.method1()
method 1
>>> x.method3()
method 3
>>> x.calls
['method2', 'method1', 'method3']
>>> x.method1()
method 1
>>> x.method1()
method 1
>>> x.calls
['method2', 'method1', 'method3', 'method1', 'method1']
You can further improve __getattr__
in Wrapper
to fit your needs. (record timestamps for the method calls, record output, log to a database, etc.)
Upvotes: 1