2

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 ?

vishnu m c
  • 841
  • 1
  • 7
  • 21

1 Answers1

1

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
ohannes
  • 514
  • 7
  • 10
  • probably yes. it is the module where your home view is defined. actually, it looks like: `from yourapp import views` – ohannes Sep 01 '17 at 10:04
  • But how here mock function works. there is no import from mock. What will be the object argument for MockPortScanner – vishnu m c Sep 01 '17 at 10:09
  • you mean builtin `mock` module? you can implement the same behavior with that as well, it is your preference. Here, you have your own mock class implemented as a real class but just for test purposes. – ohannes Sep 01 '17 at 10:14
  • `object` is the base class for **new-style** classes. see [this](https://stackoverflow.com/questions/4015417/python-class-inherits-object) btw, you can omit that part if you don't feel comfortable, like `class MockPortScanner:` – ohannes Sep 01 '17 at 10:16
  • I have written my testscases using classes. Hence i need only this in a single testcase method. When i implemented this one it works. But for all other testcase methods views return the same mock value – vishnu m c Sep 01 '17 at 10:18
  • do you need to test with mock and actual values at the same time? – ohannes Sep 01 '17 at 10:22
  • Yes. I need mock value to test a single case only. But i have to do some other tests with the same view function – vishnu m c Sep 01 '17 at 10:25
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/153453/discussion-between-ohannes-and-vishnu-m-c). – ohannes Sep 01 '17 at 10:28