3

Nose2 has this awesome Such DSL that works similar to RSpec. I used to use unittests directly and decorated the function with something like mock.patch. I am wondering how the should decorated functions differ from regular unittest functions, and how can I use other decorators as for unittest functions.

I can get it to work like this, but it seems like losing the ability of passing in the unittest instance in the arguments. Any advise will be super appreciated. Thanks!

@it.should('do something')
@mock.patch('my.package.lib.b')                                                                
@mock.patch('my.package.lib.a')                                                                   
def test(a, b):
    pass
322896
  • 956
  • 1
  • 9
  • 19

1 Answers1

1

So we know that decorator order matters and none of these work:

@it.should('do something')
@mock.patch('datetime.date')
@mock.patch('datetime.time')
def test_1(date, time, case):
    pass

@mock.patch('datetime.time')
@mock.patch('datetime.date')
@it.should('do something')
def test_2(case, date, time):
    pass

because of the way patch and should are implemented. Both libraries make some assumptions about what the resulting decorated function will be so it's not possible to directly pass a result of decoration from one to the other.

But we can make a fix for that from the outside using an "adapter" decorator:

import mock
import nose2.tools

def fix_case(f):
    def test(case):
        f(case=case)
    return test

with nose2.tools.such.A('system') as it:

    @it.should('do something')
    @fix_case
    @mock.patch('datetime.time')
    @mock.patch('datetime.date')
    def test_3(date, time, case=None):
        print(date, time, case)

it.createTests(globals())

Now this works and results in:

$ nose2 -v
test 0000: should do something (tests.test_nose2_such.A system) ...
(<MagicMock name='date' id='4334752592'>, <MagicMock name='time' id='4334762000'>,
<tests.test_nose2_such.A system testMethod=test 0000: should do something>)
ok

----------------------------------------------------------------------
Ran 1 test in 0.001s

OK

This is rather quick and dirty but get's the job done. I'll see if I can improve upon this and make it nicer.

famousgarkin
  • 13,687
  • 5
  • 58
  • 74
  • Thanks, @famousgarkin. This is very helpful and I am going to give it a try later. I really have to take a deeper look at the source of the decorator. Also I just noticed that nose2 has parameterized tests (https://nose2.readthedocs.org/en/latest/plugins/parameters.html). Maybe this is something useful? Thanks again! – 322896 Jul 08 '14 at 19:52