views:

83

answers:

2

I've got a simple class that gets most of its arguments via init, which also runs a variety of private methods that do most of the work. Output is available either through access to object variables or public methods.

Here's the problem - I'd like my unittest framework to directly call the private methods called by init with different data - without going through init.

What's the best way to do this?

So far, I've been refactoring these classes so that init does less and data is passed in separately. This makes testing easy, but I think the usability of the class suffers a little.

EDIT: Example solution based on Ignacio's answer:

import types

class C(object):

   def __init__(self, number):
       new_number = self._foo(number)
       self._bar(new_number)

   def _foo(self, number):
       return number * 2

   def _bar(self, number):
       print number * 10

#--- normal execution - should print 160: -------
MyC = C(8)

#--- testing execution - should print 80 --------
MyC = object.__new__(C)
MyC._bar(8)
+4  A: 

Why does the usability of the class have to suffer? If all the __init__ is doing is precomputing things so you can expose values as simple variables, change those variables into properties and do the computation (potentially cached/memoized) in the getter. That way your __init__ method is back to doing initialization only and testability is improved.

The downside to this approach is that it might be less performant, but probably not to a significant degree.

Hank Gay
The __init__ was actually running class functions, which eliminated the need for the user to run a separate function to run everything. However, you're right - that could be handled by properties or a getter which wouldn't result in an extra call and would make things easier to test. Thanks.
KenFar
+2  A: 

For new-style classes, call object.__new__(), passing the class as a parameter. For old-style classes, call types.InstanceType() passing the class as a parameter.

import types

class C(object):
  def __init__(self):
    print 'init'

class OldC:
  def __init__(self):
    print 'initOld'

c = object.__new__(C)
print c

oc = types.InstanceType(OldC)
print oc
Ignacio Vazquez-Abrams
This is exactly what I was looking for. I've added a simplified version of what I'm doing with it in the question.
KenFar