Decorator factory on a unittest method
<pre><code>def register_processor2(processor_name='SomeProcessor'):
    def decorator(func):
        class SomeProcessor(GenericPaymentProcessor, TriggeredProcessorMixin):
            name = processor_name
            transaction_class = Transaction

            @staticmethod
            def setup(data=None):
                pass

        @wraps(func)
        def func_wrapper(*args, **kwargs):
            PaymentProcessorManager.register(SomeProcessor)
            result = func(*args, **kwargs)
            PaymentProcessorManager.unregister(SomeProcessor)
            return result

        return func_wrapper
    return decorator


def register_processor(func):
    class SomeProcessor(GenericPaymentProcessor, TriggeredProcessorMixin):
         name = 'SomeProcessor'
         transaction_class = Transaction

         @staticmethod
         def setup(data=None):
             pass

    @wraps(func)
    def func_wrapper(*args, **kwargs):
        PaymentProcessorManager.register(SomeProcessor)
        result = func(*args, **kwargs)
        PaymentProcessorManager.unregister(SomeProcessor)
        return result

    return func_wrapper


class TestPaymentMethodEndpoints(APITestCase):
    @register_processor
    def test_put_detail_cannot_change_processor(self):
        self.assertEqual(True, False)
</code></pre>

<p>Ok so the decorator <code>register_processor</code> works as expected. And the test fails, but I want to make the name of the inner class customizable so I went for a decorator factory implementation instead.</p>

<p>The thing is when running the test decorated with <code>register_processor2</code> I get the following:</p>

<p><code>AttributeError: 'TestPaymentMethodEndpoints' object has no attribute '__name__'</code></p>

<p>This is from <code>@wraps(func)</code>, my question is why is <code>func</code> here an instance of <code>TestPaymentMethodEndpoints</code>, and not the bound method?</p>

<p>Also if I remove the <code>@wraps</code> decorator then the <strong>test runs and passes</strong>.
I'd expect that the test would not be discovered as <code>func_wrapper</code> does not start with <code>test_*</code> and even if it is discovered then it should fail.</p>

<p>Any insight on what is happening and how I'd go about doing this?</p>

<p><strong>EDIT</strong></p>

<p>So I figured it out even if the decorator factory has arguments that have default values you still need to place <code>()</code> when calling it.</p>

<p>But would still love to hear an explanation of what happened in case of the tests passing / getting discovered in the first place.</p>

<pre><code>class TestPaymentMethodEndpoints(APITestCase):
    @register_processor()
    def test_put_detail_cannot_change_processor(self):
        self.assertEqual(True, False)
</code></pre>

<p>Makes sense now that I think about it :D, gosh you learn something new each day!</p>