Using mock in testing of django application to override a function

317 Views Asked by At

I have view function that uses nmap to scan the devices in the network.

views.py

import nmap
def home(request):

   y=nmap.PortScanner()

   data = y.scan(hosts="192.168.1.*", arguments="-sP")
   context[status]=data['status']['addresses']['ipv4']
   return render_template('home.html',context)

Now i want to test this for no devices, 1 device connected and 2 or more device connected. I need to override data in tests.py.

I was thinking that it can be done using mock function. I can override it in tests.py but when simulate responses it not get override in view function.

How can i test this nmap function ?

1

There are 1 best solutions below

8
On BEST ANSWER

Monkey patching would be a good solution in your case.

Also have a look at this SO question about monkey patching

here is a possible implementation, of course you need to integrate this into your test framework.

import your_module

class MockPortScanner(object):

    # by setting this class member
    # before a test case
    # you can determine how many result
    # should be return from your view
    count = 0

    def scan(self, *args, **kwargs):
        return {
            'status': {
                'addresses': {
                    'ipv4': [i for i in range(self.count)]
                }
            }
        }

def your_test_method():
    MockPortScanner.count = 5

    request = None # create a Mock Request if you need

    # here is the mocking
    your_module.nmap.PortScanner = MockPortScanner

    # call your view as a regular function
    rv = your_module.home(request)

    # check the response

UPDATE

To have the original PortScanner later in other parts of tests, save it in the tests after importing nmap.

import nmap

OriginalPortScanner = nmap.PortScanner

Then, you will able to select the PortScanner (either original or mock) like:

views.nmap.PortScanner = OriginalPortScanner